From c7da08677d73e887380e64c865b99536027191aa Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 5 May 2013 23:13:04 +0200 Subject: 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 Signed-off-by: Jiri Kosina --- Documentation/ABI/testing/sysfs-driver-hid-wiimote | 24 +++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-driver-hid-wiimote b/Documentation/ABI/testing/sysfs-driver-hid-wiimote index 3d98009f447a..e8f6b16723e8 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid-wiimote +++ b/Documentation/ABI/testing/sysfs-driver-hid-wiimote @@ -12,7 +12,7 @@ Description: Make it possible to set/get current led state. Reading from it What: /sys/bus/hid/drivers/wiimote//extension Date: August 2011 KernelVersion: 3.2 -Contact: David Herrmann +Contact: David Herrmann Description: This file contains the currently connected and initialized extensions. It can be one of: none, motionp, nunchuck, 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 Nintendo Classic Controller extension. The motionp extension can 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//devtype +Date: May 2013 +KernelVersion: 3.11 +Contact: David Herrmann +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 -- cgit v1.2.3-59-g8ed1b From 8b1fded7a352cbd926b314d3b42a538a848c15d8 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 5 May 2013 23:13:05 +0200 Subject: HID: wiimote: add "bboard_calib" attribute Balance-Boards provide 3 16bit calibration values for each of the 4 sensors. We provide these now as 192bit value via a new "bboard_calib" sysfs attribute. We also re-read the calibration data from the device whenever user-space attempts to read this file. On normal Nintendo boards, this always produces the same results, however, on some 3rd party devices these values change until the device is fully initialized. As I have currently no idea how long to wait until it's ready (sometimes takes up to 10s?) we provide a simple workaround for users by reading this file. If we, at some point, figure out how it works, we can implement it in the kernel and provide offline data via "bboard_calib". This won't break user-space then. Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina --- Documentation/ABI/testing/sysfs-driver-hid-wiimote | 15 +++++ drivers/hid/hid-wiimote-modules.c | 68 +++++++++++++++++++++- 2 files changed, 82 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-driver-hid-wiimote b/Documentation/ABI/testing/sysfs-driver-hid-wiimote index e8f6b16723e8..ed5dd567d397 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid-wiimote +++ b/Documentation/ABI/testing/sysfs-driver-hid-wiimote @@ -42,3 +42,18 @@ Description: While a device is initialized by the wiimote driver, we perform gen10: First Wii Remote generation gen20: Second Wii Remote Plus generation (builtin MP) balanceboard: Wii Balance Board + +What: /sys/bus/hid/drivers/wiimote//bboard_calib +Date: May 2013 +KernelVersion: 3.11 +Contact: David Herrmann +Description: This attribute is only provided if the device was detected as a + balance board. It provides a single line with 3 calibration + values for all 4 sensors. The values are separated by colons and + are each 2 bytes long (encoded as 4 digit hexadecimal value). + First, 0kg values for all 4 sensors are written, followed by the + 17kg values for all 4 sensors and last the 34kg values for all 4 + sensors. + Calibration data is already applied by the kernel to all input + values but may be used by user-space to perform other + transformations. diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c index aee1b2caae13..19b8b1c4acb4 100644 --- a/drivers/hid/hid-wiimote-modules.c +++ b/drivers/hid/hid-wiimote-modules.c @@ -1380,6 +1380,60 @@ static void wiimod_bboard_close(struct input_dev *dev) spin_unlock_irqrestore(&wdata->state.lock, flags); } +static ssize_t wiimod_bboard_calib_show(struct device *dev, + struct device_attribute *attr, + char *out) +{ + struct wiimote_data *wdata = dev_to_wii(dev); + int i, j, ret; + __u16 val; + __u8 buf[24], offs; + + ret = wiimote_cmd_acquire(wdata); + if (ret) + return ret; + + ret = wiimote_cmd_read(wdata, 0xa40024, buf, 12); + if (ret != 12) { + wiimote_cmd_release(wdata); + return ret < 0 ? ret : -EIO; + } + ret = wiimote_cmd_read(wdata, 0xa40024 + 12, buf + 12, 12); + if (ret != 12) { + wiimote_cmd_release(wdata); + return ret < 0 ? ret : -EIO; + } + + wiimote_cmd_release(wdata); + + spin_lock_irq(&wdata->state.lock); + offs = 0; + for (i = 0; i < 3; ++i) { + for (j = 0; j < 4; ++j) { + wdata->state.calib_bboard[j][i] = buf[offs]; + wdata->state.calib_bboard[j][i] <<= 8; + wdata->state.calib_bboard[j][i] |= buf[offs + 1]; + offs += 2; + } + } + spin_unlock_irq(&wdata->state.lock); + + ret = 0; + for (i = 0; i < 3; ++i) { + for (j = 0; j < 4; ++j) { + val = wdata->state.calib_bboard[j][i]; + if (i == 2 && j == 3) + ret += sprintf(&out[ret], "%04x\n", val); + else + ret += sprintf(&out[ret], "%04x:", val); + } + } + + return ret; +} + +static DEVICE_ATTR(bboard_calib, S_IRUGO, wiimod_bboard_calib_show, NULL); + static int wiimod_bboard_probe(const struct wiimod_ops *ops, struct wiimote_data *wdata) { @@ -1415,6 +1469,13 @@ static int wiimod_bboard_probe(const struct wiimod_ops *ops, if (!wdata->extension.input) return -ENOMEM; + ret = device_create_file(&wdata->hdev->dev, + &dev_attr_bboard_calib); + if (ret) { + hid_err(wdata->hdev, "cannot create sysfs attribute\n"); + goto err_free; + } + input_set_drvdata(wdata->extension.input, wdata); wdata->extension.input->open = wiimod_bboard_open; wdata->extension.input->close = wiimod_bboard_close; @@ -1444,10 +1505,13 @@ static int wiimod_bboard_probe(const struct wiimod_ops *ops, ret = input_register_device(wdata->extension.input); if (ret) - goto err_free; + goto err_file; return 0; +err_file: + device_remove_file(&wdata->hdev->dev, + &dev_attr_bboard_calib); err_free: input_free_device(wdata->extension.input); wdata->extension.input = NULL; @@ -1462,6 +1526,8 @@ static void wiimod_bboard_remove(const struct wiimod_ops *ops, input_unregister_device(wdata->extension.input); wdata->extension.input = NULL; + device_remove_file(&wdata->hdev->dev, + &dev_attr_bboard_calib); } static const struct wiimod_ops wiimod_bboard = { -- cgit v1.2.3-59-g8ed1b