aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-wiimote-ext.c
diff options
context:
space:
mode:
authorFlorian Echtler <floe@butterbrot.org>2012-09-17 06:31:36 -0400
committerJiri Kosina <jkosina@suse.cz>2012-09-17 11:22:43 -0400
commit3155a09fd5060190eea4f2585d55d6c5431837c4 (patch)
tree057ef9691fb8153482fce2b8a2dfc7d6ae4e411e /drivers/hid/hid-wiimote-ext.c
parent5ad67fbc2a0f5b7e744ce2263a2340b7ebe92e00 (diff)
HID: wiimote: Parse calibration data of balance boards
The raw pressure-data that is reported by balance-boards is pretty useless unless calibration data is applied. Therefore, we read the full calibration data on extension initialization and apply it to every reported data. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com> Signed-off-by: Florian Echtler <floe@butterbrot.org> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-wiimote-ext.c')
-rw-r--r--drivers/hid/hid-wiimote-ext.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/drivers/hid/hid-wiimote-ext.c b/drivers/hid/hid-wiimote-ext.c
index ae022b863593..fc98cc9ed429 100644
--- a/drivers/hid/hid-wiimote-ext.c
+++ b/drivers/hid/hid-wiimote-ext.c
@@ -28,6 +28,7 @@ struct wiimote_ext {
28 bool mp_plugged; 28 bool mp_plugged;
29 bool motionp; 29 bool motionp;
30 __u8 ext_type; 30 __u8 ext_type;
31 __u16 calib[4][3];
31}; 32};
32 33
33enum wiiext_type { 34enum wiiext_type {
@@ -127,6 +128,7 @@ error:
127static __u8 ext_read(struct wiimote_ext *ext) 128static __u8 ext_read(struct wiimote_ext *ext)
128{ 129{
129 ssize_t ret; 130 ssize_t ret;
131 __u8 buf[24], i, j, offs = 0;
130 __u8 rmem[2], wmem; 132 __u8 rmem[2], wmem;
131 __u8 type = WIIEXT_NONE; 133 __u8 type = WIIEXT_NONE;
132 134
@@ -156,6 +158,26 @@ static __u8 ext_read(struct wiimote_ext *ext)
156 type = WIIEXT_BALANCE_BOARD; 158 type = WIIEXT_BALANCE_BOARD;
157 } 159 }
158 160
161 /* get balance board calibration data */
162 if (type == WIIEXT_BALANCE_BOARD) {
163 ret = wiimote_cmd_read(ext->wdata, 0xa40024, buf, 12);
164 ret += wiimote_cmd_read(ext->wdata, 0xa40024 + 12,
165 buf + 12, 12);
166
167 if (ret != 24) {
168 type = WIIEXT_NONE;
169 } else {
170 for (i = 0; i < 3; i++) {
171 for (j = 0; j < 4; j++) {
172 ext->calib[j][i] = buf[offs];
173 ext->calib[j][i] <<= 8;
174 ext->calib[j][i] |= buf[offs + 1];
175 offs += 2;
176 }
177 }
178 }
179 }
180
159 wiimote_cmd_release(ext->wdata); 181 wiimote_cmd_release(ext->wdata);
160 182
161 return type; 183 return type;
@@ -514,7 +536,8 @@ static void handler_classic(struct wiimote_ext *ext, const __u8 *payload)
514 536
515static void handler_balance_board(struct wiimote_ext *ext, const __u8 *payload) 537static void handler_balance_board(struct wiimote_ext *ext, const __u8 *payload)
516{ 538{
517 __s32 val[4]; 539 __s32 val[4], tmp;
540 unsigned int i;
518 541
519 /* Byte | 8 7 6 5 4 3 2 1 | 542 /* Byte | 8 7 6 5 4 3 2 1 |
520 * -----+--------------------------+ 543 * -----+--------------------------+
@@ -553,6 +576,20 @@ static void handler_balance_board(struct wiimote_ext *ext, const __u8 *payload)
553 val[3] <<= 8; 576 val[3] <<= 8;
554 val[3] |= payload[7]; 577 val[3] |= payload[7];
555 578
579 /* apply calibration data */
580 for (i = 0; i < 4; i++) {
581 if (val[i] < ext->calib[i][1]) {
582 tmp = val[i] - ext->calib[i][0];
583 tmp *= 1700;
584 tmp /= ext->calib[i][1] - ext->calib[i][0];
585 } else {
586 tmp = val[i] - ext->calib[i][1];
587 tmp *= 1700;
588 tmp /= ext->calib[i][2] - ext->calib[i][1] + 1700;
589 }
590 val[i] = tmp;
591 }
592
556 input_report_abs(ext->input, ABS_HAT0X, val[0]); 593 input_report_abs(ext->input, ABS_HAT0X, val[0]);
557 input_report_abs(ext->input, ABS_HAT0Y, val[1]); 594 input_report_abs(ext->input, ABS_HAT0Y, val[1]);
558 input_report_abs(ext->input, ABS_HAT1X, val[2]); 595 input_report_abs(ext->input, ABS_HAT1X, val[2]);