aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2013-05-05 17:13:05 -0400
committerJiri Kosina <jkosina@suse.cz>2013-06-03 05:07:05 -0400
commit8b1fded7a352cbd926b314d3b42a538a848c15d8 (patch)
tree90efd3433e991212cdd00ac9ff010e1488999b17 /drivers/hid
parentc7da08677d73e887380e64c865b99536027191aa (diff)
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 <dh.herrmann@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-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 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)
1380 spin_unlock_irqrestore(&wdata->state.lock, flags); 1380 spin_unlock_irqrestore(&wdata->state.lock, flags);
1381} 1381}
1382 1382
1383static ssize_t wiimod_bboard_calib_show(struct device *dev,
1384 struct device_attribute *attr,
1385 char *out)
1386{
1387 struct wiimote_data *wdata = dev_to_wii(dev);
1388 int i, j, ret;
1389 __u16 val;
1390 __u8 buf[24], offs;
1391
1392 ret = wiimote_cmd_acquire(wdata);
1393 if (ret)
1394 return ret;
1395
1396 ret = wiimote_cmd_read(wdata, 0xa40024, buf, 12);
1397 if (ret != 12) {
1398 wiimote_cmd_release(wdata);
1399 return ret < 0 ? ret : -EIO;
1400 }
1401 ret = wiimote_cmd_read(wdata, 0xa40024 + 12, buf + 12, 12);
1402 if (ret != 12) {
1403 wiimote_cmd_release(wdata);
1404 return ret < 0 ? ret : -EIO;
1405 }
1406
1407 wiimote_cmd_release(wdata);
1408
1409 spin_lock_irq(&wdata->state.lock);
1410 offs = 0;
1411 for (i = 0; i < 3; ++i) {
1412 for (j = 0; j < 4; ++j) {
1413 wdata->state.calib_bboard[j][i] = buf[offs];
1414 wdata->state.calib_bboard[j][i] <<= 8;
1415 wdata->state.calib_bboard[j][i] |= buf[offs + 1];
1416 offs += 2;
1417 }
1418 }
1419 spin_unlock_irq(&wdata->state.lock);
1420
1421 ret = 0;
1422 for (i = 0; i < 3; ++i) {
1423 for (j = 0; j < 4; ++j) {
1424 val = wdata->state.calib_bboard[j][i];
1425 if (i == 2 && j == 3)
1426 ret += sprintf(&out[ret], "%04x\n", val);
1427 else
1428 ret += sprintf(&out[ret], "%04x:", val);
1429 }
1430 }
1431
1432 return ret;
1433}
1434
1435static DEVICE_ATTR(bboard_calib, S_IRUGO, wiimod_bboard_calib_show, NULL);
1436
1383static int wiimod_bboard_probe(const struct wiimod_ops *ops, 1437static int wiimod_bboard_probe(const struct wiimod_ops *ops,
1384 struct wiimote_data *wdata) 1438 struct wiimote_data *wdata)
1385{ 1439{
@@ -1415,6 +1469,13 @@ static int wiimod_bboard_probe(const struct wiimod_ops *ops,
1415 if (!wdata->extension.input) 1469 if (!wdata->extension.input)
1416 return -ENOMEM; 1470 return -ENOMEM;
1417 1471
1472 ret = device_create_file(&wdata->hdev->dev,
1473 &dev_attr_bboard_calib);
1474 if (ret) {
1475 hid_err(wdata->hdev, "cannot create sysfs attribute\n");
1476 goto err_free;
1477 }
1478
1418 input_set_drvdata(wdata->extension.input, wdata); 1479 input_set_drvdata(wdata->extension.input, wdata);
1419 wdata->extension.input->open = wiimod_bboard_open; 1480 wdata->extension.input->open = wiimod_bboard_open;
1420 wdata->extension.input->close = wiimod_bboard_close; 1481 wdata->extension.input->close = wiimod_bboard_close;
@@ -1444,10 +1505,13 @@ static int wiimod_bboard_probe(const struct wiimod_ops *ops,
1444 1505
1445 ret = input_register_device(wdata->extension.input); 1506 ret = input_register_device(wdata->extension.input);
1446 if (ret) 1507 if (ret)
1447 goto err_free; 1508 goto err_file;
1448 1509
1449 return 0; 1510 return 0;
1450 1511
1512err_file:
1513 device_remove_file(&wdata->hdev->dev,
1514 &dev_attr_bboard_calib);
1451err_free: 1515err_free:
1452 input_free_device(wdata->extension.input); 1516 input_free_device(wdata->extension.input);
1453 wdata->extension.input = NULL; 1517 wdata->extension.input = NULL;
@@ -1462,6 +1526,8 @@ static void wiimod_bboard_remove(const struct wiimod_ops *ops,
1462 1526
1463 input_unregister_device(wdata->extension.input); 1527 input_unregister_device(wdata->extension.input);
1464 wdata->extension.input = NULL; 1528 wdata->extension.input = NULL;
1529 device_remove_file(&wdata->hdev->dev,
1530 &dev_attr_bboard_calib);
1465} 1531}
1466 1532
1467static const struct wiimod_ops wiimod_bboard = { 1533static const struct wiimod_ops wiimod_bboard = {