mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-24 07:31:41 +00:00
HID: wiimote: add sysfs extension/device-type attrs
Two new attributes, "extension" and "devtype" now allow user-space to read the extension type and device type. As device detection is asynchronous, we send a CHANGED event after it is done. This also allows user-space to wait for a device to settle before opening its input event devices. The "extension" device is compatible with the old "extension" sysfs field (which was registered by the static extension support code). Signed-off-by: David Herrmann <dh.herrmann@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
This commit is contained in:
parent
d76f89e13a
commit
c7da08677d
2 changed files with 128 additions and 2 deletions
|
@ -12,7 +12,7 @@ Description: Make it possible to set/get current led state. Reading from it
|
||||||
What: /sys/bus/hid/drivers/wiimote/<dev>/extension
|
What: /sys/bus/hid/drivers/wiimote/<dev>/extension
|
||||||
Date: August 2011
|
Date: August 2011
|
||||||
KernelVersion: 3.2
|
KernelVersion: 3.2
|
||||||
Contact: David Herrmann <dh.herrmann@googlemail.com>
|
Contact: David Herrmann <dh.herrmann@gmail.com>
|
||||||
Description: This file contains the currently connected and initialized
|
Description: This file contains the currently connected and initialized
|
||||||
extensions. It can be one of: none, motionp, nunchuck, classic,
|
extensions. It can be one of: none, motionp, nunchuck, classic,
|
||||||
motionp+nunchuck, motionp+classic
|
motionp+nunchuck, motionp+classic
|
||||||
|
@ -20,3 +20,25 @@ Description: This file contains the currently connected and initialized
|
||||||
the official Nintendo Nunchuck extension and classic is the
|
the official Nintendo Nunchuck extension and classic is the
|
||||||
Nintendo Classic Controller extension. The motionp extension can
|
Nintendo Classic Controller extension. The motionp extension can
|
||||||
be combined with the other two.
|
be combined with the other two.
|
||||||
|
Starting with kernel-version 3.11 Motion Plus hotplugging is
|
||||||
|
supported and if detected, it's no longer reported as static
|
||||||
|
extension. You will get uevent notifications for the motion-plus
|
||||||
|
device then.
|
||||||
|
|
||||||
|
What: /sys/bus/hid/drivers/wiimote/<dev>/devtype
|
||||||
|
Date: May 2013
|
||||||
|
KernelVersion: 3.11
|
||||||
|
Contact: David Herrmann <dh.herrmann@gmail.com>
|
||||||
|
Description: While a device is initialized by the wiimote driver, we perform
|
||||||
|
a device detection and signal a "change" uevent after it is
|
||||||
|
done. This file shows the detected device type. "pending" means
|
||||||
|
that the detection is still ongoing, "unknown" means, that the
|
||||||
|
device couldn't be detected or loaded. "generic" means, that the
|
||||||
|
device couldn't be detected but supports basic Wii Remote
|
||||||
|
features and can be used.
|
||||||
|
Other strings for each device-type are available and may be
|
||||||
|
added if new device-specific detections are added.
|
||||||
|
Currently supported are:
|
||||||
|
gen10: First Wii Remote generation
|
||||||
|
gen20: Second Wii Remote Plus generation (builtin MP)
|
||||||
|
balanceboard: Wii Balance Board
|
||||||
|
|
|
@ -1166,11 +1166,18 @@ static void wiimote_init_worker(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct wiimote_data *wdata = container_of(work, struct wiimote_data,
|
struct wiimote_data *wdata = container_of(work, struct wiimote_data,
|
||||||
init_worker);
|
init_worker);
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
if (wdata->state.devtype == WIIMOTE_DEV_PENDING)
|
if (wdata->state.devtype == WIIMOTE_DEV_PENDING) {
|
||||||
wiimote_init_detect(wdata);
|
wiimote_init_detect(wdata);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!wiimote_init_check(wdata))
|
if (!wiimote_init_check(wdata))
|
||||||
wiimote_init_hotplug(wdata);
|
wiimote_init_hotplug(wdata);
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
kobject_uevent(&wdata->hdev->dev.kobj, KOBJ_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __wiimote_schedule(struct wiimote_data *wdata)
|
void __wiimote_schedule(struct wiimote_data *wdata)
|
||||||
|
@ -1591,6 +1598,84 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t wiimote_ext_show(struct device *dev,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
struct wiimote_data *wdata = dev_to_wii(dev);
|
||||||
|
__u8 type;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&wdata->state.lock, flags);
|
||||||
|
type = wdata->state.exttype;
|
||||||
|
spin_unlock_irqrestore(&wdata->state.lock, flags);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case WIIMOTE_EXT_NONE:
|
||||||
|
return sprintf(buf, "none\n");
|
||||||
|
case WIIMOTE_EXT_NUNCHUK:
|
||||||
|
return sprintf(buf, "nunchuk\n");
|
||||||
|
case WIIMOTE_EXT_CLASSIC_CONTROLLER:
|
||||||
|
return sprintf(buf, "classic\n");
|
||||||
|
case WIIMOTE_EXT_BALANCE_BOARD:
|
||||||
|
return sprintf(buf, "balanceboard\n");
|
||||||
|
case WIIMOTE_EXT_UNKNOWN:
|
||||||
|
/* fallthrough */
|
||||||
|
default:
|
||||||
|
return sprintf(buf, "unknown\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t wiimote_ext_store(struct device *dev,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct wiimote_data *wdata = dev_to_wii(dev);
|
||||||
|
|
||||||
|
if (!strcmp(buf, "scan")) {
|
||||||
|
wiimote_schedule(wdata);
|
||||||
|
} else {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return strnlen(buf, PAGE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(extension, S_IRUGO | S_IWUSR | S_IWGRP, wiimote_ext_show,
|
||||||
|
wiimote_ext_store);
|
||||||
|
|
||||||
|
static ssize_t wiimote_dev_show(struct device *dev,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
struct wiimote_data *wdata = dev_to_wii(dev);
|
||||||
|
__u8 type;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&wdata->state.lock, flags);
|
||||||
|
type = wdata->state.devtype;
|
||||||
|
spin_unlock_irqrestore(&wdata->state.lock, flags);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case WIIMOTE_DEV_GENERIC:
|
||||||
|
return sprintf(buf, "generic\n");
|
||||||
|
case WIIMOTE_DEV_GEN10:
|
||||||
|
return sprintf(buf, "gen10\n");
|
||||||
|
case WIIMOTE_DEV_GEN20:
|
||||||
|
return sprintf(buf, "gen20\n");
|
||||||
|
case WIIMOTE_DEV_BALANCE_BOARD:
|
||||||
|
return sprintf(buf, "balanceboard\n");
|
||||||
|
case WIIMOTE_DEV_PENDING:
|
||||||
|
return sprintf(buf, "pending\n");
|
||||||
|
case WIIMOTE_DEV_UNKNOWN:
|
||||||
|
/* fallthrough */
|
||||||
|
default:
|
||||||
|
return sprintf(buf, "unknown\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(devtype, S_IRUGO, wiimote_dev_show, NULL);
|
||||||
|
|
||||||
static struct wiimote_data *wiimote_create(struct hid_device *hdev)
|
static struct wiimote_data *wiimote_create(struct hid_device *hdev)
|
||||||
{
|
{
|
||||||
struct wiimote_data *wdata;
|
struct wiimote_data *wdata;
|
||||||
|
@ -1631,6 +1716,9 @@ static void wiimote_destroy(struct wiimote_data *wdata)
|
||||||
cancel_work_sync(&wdata->init_worker);
|
cancel_work_sync(&wdata->init_worker);
|
||||||
del_timer_sync(&wdata->timer);
|
del_timer_sync(&wdata->timer);
|
||||||
|
|
||||||
|
device_remove_file(&wdata->hdev->dev, &dev_attr_devtype);
|
||||||
|
device_remove_file(&wdata->hdev->dev, &dev_attr_extension);
|
||||||
|
|
||||||
wiimote_mp_unload(wdata);
|
wiimote_mp_unload(wdata);
|
||||||
wiimote_ext_unload(wdata);
|
wiimote_ext_unload(wdata);
|
||||||
wiimote_modules_unload(wdata);
|
wiimote_modules_unload(wdata);
|
||||||
|
@ -1673,6 +1761,18 @@ static int wiimote_hid_probe(struct hid_device *hdev,
|
||||||
goto err_stop;
|
goto err_stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = device_create_file(&hdev->dev, &dev_attr_extension);
|
||||||
|
if (ret) {
|
||||||
|
hid_err(hdev, "cannot create sysfs attribute\n");
|
||||||
|
goto err_close;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = device_create_file(&hdev->dev, &dev_attr_devtype);
|
||||||
|
if (ret) {
|
||||||
|
hid_err(hdev, "cannot create sysfs attribute\n");
|
||||||
|
goto err_ext;
|
||||||
|
}
|
||||||
|
|
||||||
ret = wiidebug_init(wdata);
|
ret = wiidebug_init(wdata);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free;
|
goto err_free;
|
||||||
|
@ -1688,6 +1788,10 @@ err_free:
|
||||||
wiimote_destroy(wdata);
|
wiimote_destroy(wdata);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
err_ext:
|
||||||
|
device_remove_file(&wdata->hdev->dev, &dev_attr_extension);
|
||||||
|
err_close:
|
||||||
|
hid_hw_close(hdev);
|
||||||
err_stop:
|
err_stop:
|
||||||
hid_hw_stop(hdev);
|
hid_hw_stop(hdev);
|
||||||
err:
|
err:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue