aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/joystick
diff options
context:
space:
mode:
authorPierre-Loup A. Griffais <pgriffais@valvesoftware.com>2015-10-10 12:34:17 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2015-10-10 14:27:30 -0400
commitb8154002cbdfde1aed2f86bd27f5e2c7e832cabb (patch)
tree5a1949954f6465de9fa0a3be49b230dfeafa6cf8 /drivers/input/joystick
parent5ee8bda943de20017636845a5c8d7069a4a283b8 (diff)
Input: xpad - move the input device creation to a new function
To allow us to later create / destroy the input device from the urb callback, we need to initialize/ deinitialize the input device from a separate function. So pull that logic out now to make later patches more "obvious" as to what they do. Signed-off-by: "Pierre-Loup A. Griffais" <pgriffais@valvesoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Pavel Rojtberg <rojtberg@gmail.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input/joystick')
-rw-r--r--drivers/input/joystick/xpad.c211
1 files changed, 119 insertions, 92 deletions
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index bd669c1ff380..486db7a1d99a 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -342,6 +342,7 @@ struct usb_xpad {
342 int mapping; /* map d-pad to buttons or to axes */ 342 int mapping; /* map d-pad to buttons or to axes */
343 int xtype; /* type of xbox device */ 343 int xtype; /* type of xbox device */
344 int pad_nr; /* the order x360 pads were attached */ 344 int pad_nr; /* the order x360 pads were attached */
345 const char *name; /* name of the device */
345}; 346};
346 347
347/* 348/*
@@ -1060,91 +1061,36 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
1060 } 1061 }
1061} 1062}
1062 1063
1063static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) 1064static void xpad_deinit_input(struct usb_xpad *xpad)
1065{
1066 xpad_led_disconnect(xpad);
1067 input_unregister_device(xpad->dev);
1068}
1069
1070static int xpad_init_input(struct usb_xpad *xpad)
1064{ 1071{
1065 struct usb_device *udev = interface_to_usbdev(intf);
1066 struct usb_xpad *xpad;
1067 struct input_dev *input_dev; 1072 struct input_dev *input_dev;
1068 struct usb_endpoint_descriptor *ep_irq_in;
1069 int ep_irq_in_idx;
1070 int i, error; 1073 int i, error;
1071 1074
1072 for (i = 0; xpad_device[i].idVendor; i++) {
1073 if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
1074 (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
1075 break;
1076 }
1077
1078 if (xpad_device[i].xtype == XTYPE_XBOXONE &&
1079 intf->cur_altsetting->desc.bInterfaceNumber != 0) {
1080 /*
1081 * The Xbox One controller lists three interfaces all with the
1082 * same interface class, subclass and protocol. Differentiate by
1083 * interface number.
1084 */
1085 return -ENODEV;
1086 }
1087
1088 xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);
1089 input_dev = input_allocate_device(); 1075 input_dev = input_allocate_device();
1090 if (!xpad || !input_dev) { 1076 if (!input_dev)
1091 error = -ENOMEM; 1077 return -ENOMEM;
1092 goto fail1;
1093 }
1094
1095 xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN,
1096 GFP_KERNEL, &xpad->idata_dma);
1097 if (!xpad->idata) {
1098 error = -ENOMEM;
1099 goto fail1;
1100 }
1101
1102 xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
1103 if (!xpad->irq_in) {
1104 error = -ENOMEM;
1105 goto fail2;
1106 }
1107
1108 xpad->udev = udev;
1109 xpad->intf = intf;
1110 xpad->mapping = xpad_device[i].mapping;
1111 xpad->xtype = xpad_device[i].xtype;
1112
1113 if (xpad->xtype == XTYPE_UNKNOWN) {
1114 if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
1115 if (intf->cur_altsetting->desc.bInterfaceProtocol == 129)
1116 xpad->xtype = XTYPE_XBOX360W;
1117 else
1118 xpad->xtype = XTYPE_XBOX360;
1119 } else
1120 xpad->xtype = XTYPE_XBOX;
1121
1122 if (dpad_to_buttons)
1123 xpad->mapping |= MAP_DPAD_TO_BUTTONS;
1124 if (triggers_to_buttons)
1125 xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS;
1126 if (sticks_to_null)
1127 xpad->mapping |= MAP_STICKS_TO_NULL;
1128 }
1129 1078
1130 xpad->dev = input_dev; 1079 xpad->dev = input_dev;
1131 usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); 1080 input_dev->name = xpad->name;
1132 strlcat(xpad->phys, "/input0", sizeof(xpad->phys));
1133
1134 input_dev->name = xpad_device[i].name;
1135 input_dev->phys = xpad->phys; 1081 input_dev->phys = xpad->phys;
1136 usb_to_input_id(udev, &input_dev->id); 1082 usb_to_input_id(xpad->udev, &input_dev->id);
1137 input_dev->dev.parent = &intf->dev; 1083 input_dev->dev.parent = &xpad->intf->dev;
1138 1084
1139 input_set_drvdata(input_dev, xpad); 1085 input_set_drvdata(input_dev, xpad);
1140 1086
1141 input_dev->open = xpad_open; 1087 input_dev->open = xpad_open;
1142 input_dev->close = xpad_close; 1088 input_dev->close = xpad_close;
1143 1089
1144 input_dev->evbit[0] = BIT_MASK(EV_KEY); 1090 __set_bit(EV_KEY, input_dev->evbit);
1145 1091
1146 if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { 1092 if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
1147 input_dev->evbit[0] |= BIT_MASK(EV_ABS); 1093 __set_bit(EV_ABS, input_dev->evbit);
1148 /* set up axes */ 1094 /* set up axes */
1149 for (i = 0; xpad_abs[i] >= 0; i++) 1095 for (i = 0; xpad_abs[i] >= 0; i++)
1150 xpad_set_up_abs(input_dev, xpad_abs[i]); 1096 xpad_set_up_abs(input_dev, xpad_abs[i]);
@@ -1189,17 +1135,100 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
1189 xpad_set_up_abs(input_dev, xpad_abs_triggers[i]); 1135 xpad_set_up_abs(input_dev, xpad_abs_triggers[i]);
1190 } 1136 }
1191 1137
1192 error = xpad_init_output(intf, xpad);
1193 if (error)
1194 goto fail3;
1195
1196 error = xpad_init_ff(xpad); 1138 error = xpad_init_ff(xpad);
1197 if (error) 1139 if (error)
1198 goto fail4; 1140 goto err_free_input;
1199 1141
1200 error = xpad_led_probe(xpad); 1142 error = xpad_led_probe(xpad);
1201 if (error) 1143 if (error)
1202 goto fail5; 1144 goto err_destroy_ff;
1145
1146 error = input_register_device(xpad->dev);
1147 if (error)
1148 goto err_disconnect_led;
1149
1150 return 0;
1151
1152err_disconnect_led:
1153 xpad_led_disconnect(xpad);
1154err_destroy_ff:
1155 input_ff_destroy(input_dev);
1156err_free_input:
1157 input_free_device(input_dev);
1158 return error;
1159}
1160
1161static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
1162{
1163 struct usb_device *udev = interface_to_usbdev(intf);
1164 struct usb_xpad *xpad;
1165 struct usb_endpoint_descriptor *ep_irq_in;
1166 int ep_irq_in_idx;
1167 int i, error;
1168
1169 for (i = 0; xpad_device[i].idVendor; i++) {
1170 if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
1171 (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
1172 break;
1173 }
1174
1175 if (xpad_device[i].xtype == XTYPE_XBOXONE &&
1176 intf->cur_altsetting->desc.bInterfaceNumber != 0) {
1177 /*
1178 * The Xbox One controller lists three interfaces all with the
1179 * same interface class, subclass and protocol. Differentiate by
1180 * interface number.
1181 */
1182 return -ENODEV;
1183 }
1184
1185 xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);
1186 if (!xpad)
1187 return -ENOMEM;
1188
1189 usb_make_path(udev, xpad->phys, sizeof(xpad->phys));
1190 strlcat(xpad->phys, "/input0", sizeof(xpad->phys));
1191
1192 xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN,
1193 GFP_KERNEL, &xpad->idata_dma);
1194 if (!xpad->idata) {
1195 error = -ENOMEM;
1196 goto err_free_mem;
1197 }
1198
1199 xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
1200 if (!xpad->irq_in) {
1201 error = -ENOMEM;
1202 goto err_free_idata;
1203 }
1204
1205 xpad->udev = udev;
1206 xpad->intf = intf;
1207 xpad->mapping = xpad_device[i].mapping;
1208 xpad->xtype = xpad_device[i].xtype;
1209 xpad->name = xpad_device[i].name;
1210
1211 if (xpad->xtype == XTYPE_UNKNOWN) {
1212 if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
1213 if (intf->cur_altsetting->desc.bInterfaceProtocol == 129)
1214 xpad->xtype = XTYPE_XBOX360W;
1215 else
1216 xpad->xtype = XTYPE_XBOX360;
1217 } else {
1218 xpad->xtype = XTYPE_XBOX;
1219 }
1220
1221 if (dpad_to_buttons)
1222 xpad->mapping |= MAP_DPAD_TO_BUTTONS;
1223 if (triggers_to_buttons)
1224 xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS;
1225 if (sticks_to_null)
1226 xpad->mapping |= MAP_STICKS_TO_NULL;
1227 }
1228
1229 error = xpad_init_output(intf, xpad);
1230 if (error)
1231 goto err_free_in_urb;
1203 1232
1204 /* Xbox One controller has in/out endpoints swapped. */ 1233 /* Xbox One controller has in/out endpoints swapped. */
1205 ep_irq_in_idx = xpad->xtype == XTYPE_XBOXONE ? 1 : 0; 1234 ep_irq_in_idx = xpad->xtype == XTYPE_XBOXONE ? 1 : 0;
@@ -1212,12 +1241,12 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
1212 xpad->irq_in->transfer_dma = xpad->idata_dma; 1241 xpad->irq_in->transfer_dma = xpad->idata_dma;
1213 xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 1242 xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
1214 1243
1215 error = input_register_device(xpad->dev);
1216 if (error)
1217 goto fail6;
1218
1219 usb_set_intfdata(intf, xpad); 1244 usb_set_intfdata(intf, xpad);
1220 1245
1246 error = xpad_init_input(xpad);
1247 if (error)
1248 goto err_deinit_output;
1249
1221 if (xpad->xtype == XTYPE_XBOX360W) { 1250 if (xpad->xtype == XTYPE_XBOX360W) {
1222 /* 1251 /*
1223 * Submit the int URB immediately rather than waiting for open 1252 * Submit the int URB immediately rather than waiting for open
@@ -1229,20 +1258,19 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
1229 xpad->irq_in->dev = xpad->udev; 1258 xpad->irq_in->dev = xpad->udev;
1230 error = usb_submit_urb(xpad->irq_in, GFP_KERNEL); 1259 error = usb_submit_urb(xpad->irq_in, GFP_KERNEL);
1231 if (error) 1260 if (error)
1232 goto fail7; 1261 goto err_deinit_input;
1233 } 1262 }
1234
1235 return 0; 1263 return 0;
1236 1264
1237 fail7: input_unregister_device(input_dev); 1265err_deinit_input:
1238 input_dev = NULL; 1266 xpad_deinit_input(xpad);
1239 fail6: xpad_led_disconnect(xpad); 1267err_deinit_output:
1240 fail5: if (input_dev) 1268 xpad_deinit_output(xpad);
1241 input_ff_destroy(input_dev); 1269err_free_in_urb:
1242 fail4: xpad_deinit_output(xpad); 1270 usb_free_urb(xpad->irq_in);
1243 fail3: usb_free_urb(xpad->irq_in); 1271err_free_idata:
1244 fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); 1272 usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
1245 fail1: input_free_device(input_dev); 1273err_free_mem:
1246 kfree(xpad); 1274 kfree(xpad);
1247 return error; 1275 return error;
1248 1276
@@ -1252,8 +1280,7 @@ static void xpad_disconnect(struct usb_interface *intf)
1252{ 1280{
1253 struct usb_xpad *xpad = usb_get_intfdata (intf); 1281 struct usb_xpad *xpad = usb_get_intfdata (intf);
1254 1282
1255 xpad_led_disconnect(xpad); 1283 xpad_deinit_input(xpad);
1256 input_unregister_device(xpad->dev);
1257 xpad_deinit_output(xpad); 1284 xpad_deinit_output(xpad);
1258 1285
1259 if (xpad->xtype == XTYPE_XBOX360W) { 1286 if (xpad->xtype == XTYPE_XBOX360W) {