diff options
author | Pierre-Loup A. Griffais <pgriffais@valvesoftware.com> | 2015-10-10 12:34:17 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2015-10-10 14:27:30 -0400 |
commit | b8154002cbdfde1aed2f86bd27f5e2c7e832cabb (patch) | |
tree | 5a1949954f6465de9fa0a3be49b230dfeafa6cf8 /drivers/input/joystick | |
parent | 5ee8bda943de20017636845a5c8d7069a4a283b8 (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.c | 211 |
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 | ||
1063 | static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) | 1064 | static void xpad_deinit_input(struct usb_xpad *xpad) |
1065 | { | ||
1066 | xpad_led_disconnect(xpad); | ||
1067 | input_unregister_device(xpad->dev); | ||
1068 | } | ||
1069 | |||
1070 | static 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 | |||
1152 | err_disconnect_led: | ||
1153 | xpad_led_disconnect(xpad); | ||
1154 | err_destroy_ff: | ||
1155 | input_ff_destroy(input_dev); | ||
1156 | err_free_input: | ||
1157 | input_free_device(input_dev); | ||
1158 | return error; | ||
1159 | } | ||
1160 | |||
1161 | static 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); | 1265 | err_deinit_input: |
1238 | input_dev = NULL; | 1266 | xpad_deinit_input(xpad); |
1239 | fail6: xpad_led_disconnect(xpad); | 1267 | err_deinit_output: |
1240 | fail5: if (input_dev) | 1268 | xpad_deinit_output(xpad); |
1241 | input_ff_destroy(input_dev); | 1269 | err_free_in_urb: |
1242 | fail4: xpad_deinit_output(xpad); | 1270 | usb_free_urb(xpad->irq_in); |
1243 | fail3: usb_free_urb(xpad->irq_in); | 1271 | err_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); | 1273 | err_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) { |