aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2013-05-05 17:13:00 -0400
committerJiri Kosina <jkosina@suse.cz>2013-06-03 05:07:03 -0400
commit9d6f9ecb0cbf714f39c0ae492fe8678bcb93a001 (patch)
tree673e3e906b49c1e0b9672e5e54a2a52f4cb12bff /drivers/hid
parentb6ee67b37c02790ba9bd170ee1fe0d2cd2941001 (diff)
HID: wiimote: add Classic Controller extension
Add a new extension module for the classic controller so we get hotplug support for this device. It is mostly the same as the old static classic controller parser. 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-core.c6
-rw-r--r--drivers/hid/hid-wiimote-modules.c279
-rw-r--r--drivers/hid/hid-wiimote.h1
3 files changed, 286 insertions, 0 deletions
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c
index dedf3c84e243..f6c4773fac56 100644
--- a/drivers/hid/hid-wiimote-core.c
+++ b/drivers/hid/hid-wiimote-core.c
@@ -446,6 +446,8 @@ static __u8 wiimote_cmd_read_ext(struct wiimote_data *wdata, __u8 *rmem)
446 446
447 if (rmem[4] == 0x00 && rmem[5] == 0x00) 447 if (rmem[4] == 0x00 && rmem[5] == 0x00)
448 return WIIMOTE_EXT_NUNCHUK; 448 return WIIMOTE_EXT_NUNCHUK;
449 if (rmem[4] == 0x01 && rmem[5] == 0x01)
450 return WIIMOTE_EXT_CLASSIC_CONTROLLER;
449 if (rmem[4] == 0x04 && rmem[5] == 0x02) 451 if (rmem[4] == 0x04 && rmem[5] == 0x02)
450 return WIIMOTE_EXT_BALANCE_BOARD; 452 return WIIMOTE_EXT_BALANCE_BOARD;
451 453
@@ -480,6 +482,9 @@ static bool wiimote_cmd_map_mp(struct wiimote_data *wdata, __u8 exttype)
480 482
481 /* map MP with correct pass-through mode */ 483 /* map MP with correct pass-through mode */
482 switch (exttype) { 484 switch (exttype) {
485 case WIIMOTE_EXT_CLASSIC_CONTROLLER:
486 wmem = 0x07;
487 break;
483 case WIIMOTE_EXT_NUNCHUK: 488 case WIIMOTE_EXT_NUNCHUK:
484 wmem = 0x05; 489 wmem = 0x05;
485 break; 490 break;
@@ -1040,6 +1045,7 @@ static const char *wiimote_exttype_names[WIIMOTE_EXT_NUM] = {
1040 [WIIMOTE_EXT_NONE] = "None", 1045 [WIIMOTE_EXT_NONE] = "None",
1041 [WIIMOTE_EXT_UNKNOWN] = "Unknown", 1046 [WIIMOTE_EXT_UNKNOWN] = "Unknown",
1042 [WIIMOTE_EXT_NUNCHUK] = "Nintendo Wii Nunchuk", 1047 [WIIMOTE_EXT_NUNCHUK] = "Nintendo Wii Nunchuk",
1048 [WIIMOTE_EXT_CLASSIC_CONTROLLER] = "Nintendo Wii Classic Controller",
1043 [WIIMOTE_EXT_BALANCE_BOARD] = "Nintendo Wii Balance Board", 1049 [WIIMOTE_EXT_BALANCE_BOARD] = "Nintendo Wii Balance Board",
1044}; 1050};
1045 1051
diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c
index e4bcc098bdfd..daeb679f98ff 100644
--- a/drivers/hid/hid-wiimote-modules.c
+++ b/drivers/hid/hid-wiimote-modules.c
@@ -986,6 +986,284 @@ static const struct wiimod_ops wiimod_nunchuk = {
986}; 986};
987 987
988/* 988/*
989 * Classic Controller
990 * Another official extension from Nintendo. It provides a classic
991 * gamecube-like controller that can be hotplugged on the Wii Remote.
992 * It has several hardware buttons and switches that are all reported via
993 * a normal extension device.
994 */
995
996enum wiimod_classic_keys {
997 WIIMOD_CLASSIC_KEY_A,
998 WIIMOD_CLASSIC_KEY_B,
999 WIIMOD_CLASSIC_KEY_X,
1000 WIIMOD_CLASSIC_KEY_Y,
1001 WIIMOD_CLASSIC_KEY_ZL,
1002 WIIMOD_CLASSIC_KEY_ZR,
1003 WIIMOD_CLASSIC_KEY_PLUS,
1004 WIIMOD_CLASSIC_KEY_MINUS,
1005 WIIMOD_CLASSIC_KEY_HOME,
1006 WIIMOD_CLASSIC_KEY_LEFT,
1007 WIIMOD_CLASSIC_KEY_RIGHT,
1008 WIIMOD_CLASSIC_KEY_UP,
1009 WIIMOD_CLASSIC_KEY_DOWN,
1010 WIIMOD_CLASSIC_KEY_LT,
1011 WIIMOD_CLASSIC_KEY_RT,
1012 WIIMOD_CLASSIC_KEY_NUM,
1013};
1014
1015static const __u16 wiimod_classic_map[] = {
1016 BTN_A, /* WIIMOD_CLASSIC_KEY_A */
1017 BTN_B, /* WIIMOD_CLASSIC_KEY_B */
1018 BTN_X, /* WIIMOD_CLASSIC_KEY_X */
1019 BTN_Y, /* WIIMOD_CLASSIC_KEY_Y */
1020 BTN_TL2, /* WIIMOD_CLASSIC_KEY_ZL */
1021 BTN_TR2, /* WIIMOD_CLASSIC_KEY_ZR */
1022 KEY_NEXT, /* WIIMOD_CLASSIC_KEY_PLUS */
1023 KEY_PREVIOUS, /* WIIMOD_CLASSIC_KEY_MINUS */
1024 BTN_MODE, /* WIIMOD_CLASSIC_KEY_HOME */
1025 KEY_LEFT, /* WIIMOD_CLASSIC_KEY_LEFT */
1026 KEY_RIGHT, /* WIIMOD_CLASSIC_KEY_RIGHT */
1027 KEY_UP, /* WIIMOD_CLASSIC_KEY_UP */
1028 KEY_DOWN, /* WIIMOD_CLASSIC_KEY_DOWN */
1029 BTN_TL, /* WIIMOD_CLASSIC_KEY_LT */
1030 BTN_TR, /* WIIMOD_CLASSIC_KEY_RT */
1031};
1032
1033static void wiimod_classic_in_ext(struct wiimote_data *wdata, const __u8 *ext)
1034{
1035 __s8 rx, ry, lx, ly, lt, rt;
1036
1037 /* Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
1038 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
1039 * 1 | RX <5:4> | LX <5:0> |
1040 * 2 | RX <3:2> | LY <5:0> |
1041 * -----+-----+-----+-----+-----------------------------+
1042 * 3 |RX<1>| LT <5:4> | RY <5:1> |
1043 * -----+-----+-----------+-----------------------------+
1044 * 4 | LT <3:1> | RT <5:1> |
1045 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
1046 * 5 | BDR | BDD | BLT | B- | BH | B+ | BRT | 1 |
1047 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
1048 * 6 | BZL | BB | BY | BA | BX | BZR | BDL | BDU |
1049 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
1050 * All buttons are 0 if pressed
1051 * RX and RY are right analog stick
1052 * LX and LY are left analog stick
1053 * LT is left trigger, RT is right trigger
1054 * BLT is 0 if left trigger is fully pressed
1055 * BRT is 0 if right trigger is fully pressed
1056 * BDR, BDD, BDL, BDU form the D-Pad with right, down, left, up buttons
1057 * BZL is left Z button and BZR is right Z button
1058 * B-, BH, B+ are +, HOME and - buttons
1059 * BB, BY, BA, BX are A, B, X, Y buttons
1060 * LSB of RX, RY, LT, and RT are not transmitted and always 0.
1061 *
1062 * With motionp enabled it changes slightly to this:
1063 * Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
1064 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
1065 * 1 | RX <4:3> | LX <5:1> | BDU |
1066 * 2 | RX <2:1> | LY <5:1> | BDL |
1067 * -----+-----+-----+-----+-----------------------+-----+
1068 * 3 |RX<0>| LT <4:3> | RY <4:0> |
1069 * -----+-----+-----------+-----------------------------+
1070 * 4 | LT <2:0> | RT <4:0> |
1071 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
1072 * 5 | BDR | BDD | BLT | B- | BH | B+ | BRT | EXT |
1073 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
1074 * 6 | BZL | BB | BY | BA | BX | BZR | 0 | 0 |
1075 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
1076 * Only the LSBs of LX and LY are lost. BDU and BDL are moved, the rest
1077 * is the same as before.
1078 */
1079
1080 if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) {
1081 lx = ext[0] & 0x3e;
1082 ly = ext[0] & 0x3e;
1083 } else {
1084 lx = ext[0] & 0x3f;
1085 ly = ext[0] & 0x3f;
1086 }
1087
1088 rx = (ext[0] >> 3) & 0x14;
1089 rx |= (ext[1] >> 5) & 0x06;
1090 rx |= (ext[2] >> 7) & 0x01;
1091 ry = ext[2] & 0x1f;
1092
1093 rt = ext[3] & 0x1f;
1094 lt = (ext[2] >> 2) & 0x18;
1095 lt |= (ext[3] >> 5) & 0x07;
1096
1097 rx <<= 1;
1098 ry <<= 1;
1099 rt <<= 1;
1100 lt <<= 1;
1101
1102 input_report_abs(wdata->extension.input, ABS_HAT1X, lx - 0x20);
1103 input_report_abs(wdata->extension.input, ABS_HAT1Y, ly - 0x20);
1104 input_report_abs(wdata->extension.input, ABS_HAT2X, rx - 0x20);
1105 input_report_abs(wdata->extension.input, ABS_HAT2Y, ry - 0x20);
1106 input_report_abs(wdata->extension.input, ABS_HAT3X, rt - 0x20);
1107 input_report_abs(wdata->extension.input, ABS_HAT3Y, lt - 0x20);
1108
1109 input_report_key(wdata->extension.input,
1110 wiimod_classic_map[WIIMOD_CLASSIC_KEY_RIGHT],
1111 !(ext[4] & 0x80));
1112 input_report_key(wdata->extension.input,
1113 wiimod_classic_map[WIIMOD_CLASSIC_KEY_DOWN],
1114 !(ext[4] & 0x40));
1115 input_report_key(wdata->extension.input,
1116 wiimod_classic_map[WIIMOD_CLASSIC_KEY_LT],
1117 !(ext[4] & 0x20));
1118 input_report_key(wdata->extension.input,
1119 wiimod_classic_map[WIIMOD_CLASSIC_KEY_MINUS],
1120 !(ext[4] & 0x10));
1121 input_report_key(wdata->extension.input,
1122 wiimod_classic_map[WIIMOD_CLASSIC_KEY_HOME],
1123 !(ext[4] & 0x08));
1124 input_report_key(wdata->extension.input,
1125 wiimod_classic_map[WIIMOD_CLASSIC_KEY_PLUS],
1126 !(ext[4] & 0x04));
1127 input_report_key(wdata->extension.input,
1128 wiimod_classic_map[WIIMOD_CLASSIC_KEY_RT],
1129 !(ext[4] & 0x02));
1130 input_report_key(wdata->extension.input,
1131 wiimod_classic_map[WIIMOD_CLASSIC_KEY_ZL],
1132 !(ext[5] & 0x80));
1133 input_report_key(wdata->extension.input,
1134 wiimod_classic_map[WIIMOD_CLASSIC_KEY_B],
1135 !(ext[5] & 0x40));
1136 input_report_key(wdata->extension.input,
1137 wiimod_classic_map[WIIMOD_CLASSIC_KEY_Y],
1138 !(ext[5] & 0x20));
1139 input_report_key(wdata->extension.input,
1140 wiimod_classic_map[WIIMOD_CLASSIC_KEY_A],
1141 !(ext[5] & 0x10));
1142 input_report_key(wdata->extension.input,
1143 wiimod_classic_map[WIIMOD_CLASSIC_KEY_X],
1144 !(ext[5] & 0x08));
1145 input_report_key(wdata->extension.input,
1146 wiimod_classic_map[WIIMOD_CLASSIC_KEY_ZR],
1147 !(ext[5] & 0x04));
1148
1149 if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) {
1150 input_report_key(wdata->extension.input,
1151 wiimod_classic_map[WIIMOD_CLASSIC_KEY_LEFT],
1152 !(ext[1] & 0x01));
1153 input_report_key(wdata->extension.input,
1154 wiimod_classic_map[WIIMOD_CLASSIC_KEY_UP],
1155 !(ext[0] & 0x01));
1156 } else {
1157 input_report_key(wdata->extension.input,
1158 wiimod_classic_map[WIIMOD_CLASSIC_KEY_LEFT],
1159 !(ext[5] & 0x02));
1160 input_report_key(wdata->extension.input,
1161 wiimod_classic_map[WIIMOD_CLASSIC_KEY_UP],
1162 !(ext[5] & 0x01));
1163 }
1164
1165 input_sync(wdata->extension.input);
1166}
1167
1168static int wiimod_classic_open(struct input_dev *dev)
1169{
1170 struct wiimote_data *wdata = input_get_drvdata(dev);
1171 unsigned long flags;
1172
1173 spin_lock_irqsave(&wdata->state.lock, flags);
1174 wdata->state.flags |= WIIPROTO_FLAG_EXT_USED;
1175 wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
1176 spin_unlock_irqrestore(&wdata->state.lock, flags);
1177
1178 return 0;
1179}
1180
1181static void wiimod_classic_close(struct input_dev *dev)
1182{
1183 struct wiimote_data *wdata = input_get_drvdata(dev);
1184 unsigned long flags;
1185
1186 spin_lock_irqsave(&wdata->state.lock, flags);
1187 wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED;
1188 wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
1189 spin_unlock_irqrestore(&wdata->state.lock, flags);
1190}
1191
1192static int wiimod_classic_probe(const struct wiimod_ops *ops,
1193 struct wiimote_data *wdata)
1194{
1195 int ret, i;
1196
1197 wdata->extension.input = input_allocate_device();
1198 if (!wdata->extension.input)
1199 return -ENOMEM;
1200
1201 input_set_drvdata(wdata->extension.input, wdata);
1202 wdata->extension.input->open = wiimod_classic_open;
1203 wdata->extension.input->close = wiimod_classic_close;
1204 wdata->extension.input->dev.parent = &wdata->hdev->dev;
1205 wdata->extension.input->id.bustype = wdata->hdev->bus;
1206 wdata->extension.input->id.vendor = wdata->hdev->vendor;
1207 wdata->extension.input->id.product = wdata->hdev->product;
1208 wdata->extension.input->id.version = wdata->hdev->version;
1209 wdata->extension.input->name = WIIMOTE_NAME " Classic Controller";
1210
1211 set_bit(EV_KEY, wdata->extension.input->evbit);
1212 for (i = 0; i < WIIMOD_CLASSIC_KEY_NUM; ++i)
1213 set_bit(wiimod_classic_map[i],
1214 wdata->extension.input->keybit);
1215
1216 set_bit(EV_ABS, wdata->extension.input->evbit);
1217 set_bit(ABS_HAT1X, wdata->extension.input->absbit);
1218 set_bit(ABS_HAT1Y, wdata->extension.input->absbit);
1219 set_bit(ABS_HAT2X, wdata->extension.input->absbit);
1220 set_bit(ABS_HAT2Y, wdata->extension.input->absbit);
1221 set_bit(ABS_HAT3X, wdata->extension.input->absbit);
1222 set_bit(ABS_HAT3Y, wdata->extension.input->absbit);
1223 input_set_abs_params(wdata->extension.input,
1224 ABS_HAT1X, -30, 30, 1, 1);
1225 input_set_abs_params(wdata->extension.input,
1226 ABS_HAT1Y, -30, 30, 1, 1);
1227 input_set_abs_params(wdata->extension.input,
1228 ABS_HAT2X, -30, 30, 1, 1);
1229 input_set_abs_params(wdata->extension.input,
1230 ABS_HAT2Y, -30, 30, 1, 1);
1231 input_set_abs_params(wdata->extension.input,
1232 ABS_HAT3X, -30, 30, 1, 1);
1233 input_set_abs_params(wdata->extension.input,
1234 ABS_HAT3Y, -30, 30, 1, 1);
1235
1236 ret = input_register_device(wdata->extension.input);
1237 if (ret)
1238 goto err_free;
1239
1240 return 0;
1241
1242err_free:
1243 input_free_device(wdata->extension.input);
1244 wdata->extension.input = NULL;
1245 return ret;
1246}
1247
1248static void wiimod_classic_remove(const struct wiimod_ops *ops,
1249 struct wiimote_data *wdata)
1250{
1251 if (!wdata->extension.input)
1252 return;
1253
1254 input_unregister_device(wdata->extension.input);
1255 wdata->extension.input = NULL;
1256}
1257
1258static const struct wiimod_ops wiimod_classic = {
1259 .flags = 0,
1260 .arg = 0,
1261 .probe = wiimod_classic_probe,
1262 .remove = wiimod_classic_remove,
1263 .in_ext = wiimod_classic_in_ext,
1264};
1265
1266/*
989 * Balance Board Extension 1267 * Balance Board Extension
990 * The Nintendo Wii Balance Board provides four hardware weight sensor plus a 1268 * The Nintendo Wii Balance Board provides four hardware weight sensor plus a
991 * single push button. No other peripherals are available. However, the 1269 * single push button. No other peripherals are available. However, the
@@ -1224,5 +1502,6 @@ const struct wiimod_ops *wiimod_ext_table[WIIMOTE_EXT_NUM] = {
1224 [WIIMOTE_EXT_NONE] = &wiimod_dummy, 1502 [WIIMOTE_EXT_NONE] = &wiimod_dummy,
1225 [WIIMOTE_EXT_UNKNOWN] = &wiimod_dummy, 1503 [WIIMOTE_EXT_UNKNOWN] = &wiimod_dummy,
1226 [WIIMOTE_EXT_NUNCHUK] = &wiimod_nunchuk, 1504 [WIIMOTE_EXT_NUNCHUK] = &wiimod_nunchuk,
1505 [WIIMOTE_EXT_CLASSIC_CONTROLLER] = &wiimod_classic,
1227 [WIIMOTE_EXT_BALANCE_BOARD] = &wiimod_bboard, 1506 [WIIMOTE_EXT_BALANCE_BOARD] = &wiimod_bboard,
1228}; 1507};
diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h
index 3414e4cdc4ff..118520a79211 100644
--- a/drivers/hid/hid-wiimote.h
+++ b/drivers/hid/hid-wiimote.h
@@ -81,6 +81,7 @@ enum wiimote_exttype {
81 WIIMOTE_EXT_NONE, 81 WIIMOTE_EXT_NONE,
82 WIIMOTE_EXT_UNKNOWN, 82 WIIMOTE_EXT_UNKNOWN,
83 WIIMOTE_EXT_NUNCHUK, 83 WIIMOTE_EXT_NUNCHUK,
84 WIIMOTE_EXT_CLASSIC_CONTROLLER,
84 WIIMOTE_EXT_BALANCE_BOARD, 85 WIIMOTE_EXT_BALANCE_BOARD,
85 WIIMOTE_EXT_NUM, 86 WIIMOTE_EXT_NUM,
86}; 87};