summaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-wiimote-modules.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-wiimote-modules.c')
-rw-r--r--drivers/hid/hid-wiimote-modules.c68
1 files changed, 67 insertions, 1 deletions
diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c
index aee1b2c..19b8b1c 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 = {
OpenPOWER on IntegriCloud