diff options
author | Florian Echtler <floe@butterbrot.org> | 2012-09-17 06:31:36 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2012-09-17 11:22:43 -0400 |
commit | 3155a09fd5060190eea4f2585d55d6c5431837c4 (patch) | |
tree | 057ef9691fb8153482fce2b8a2dfc7d6ae4e411e /drivers/hid/hid-wiimote-ext.c | |
parent | 5ad67fbc2a0f5b7e744ce2263a2340b7ebe92e00 (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.c | 39 |
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 | ||
33 | enum wiiext_type { | 34 | enum wiiext_type { |
@@ -127,6 +128,7 @@ error: | |||
127 | static __u8 ext_read(struct wiimote_ext *ext) | 128 | static __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 | ||
515 | static void handler_balance_board(struct wiimote_ext *ext, const __u8 *payload) | 537 | static 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]); |