diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/hid/hid-input.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/hid/hid-input.c')
-rw-r--r-- | drivers/hid/hid-input.c | 392 |
1 files changed, 53 insertions, 339 deletions
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 21b196c394b..1483c8296d5 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -32,8 +32,6 @@ | |||
32 | #include <linux/hid.h> | 32 | #include <linux/hid.h> |
33 | #include <linux/hid-debug.h> | 33 | #include <linux/hid-debug.h> |
34 | 34 | ||
35 | #include "hid-ids.h" | ||
36 | |||
37 | #define unk KEY_UNKNOWN | 35 | #define unk KEY_UNKNOWN |
38 | 36 | ||
39 | static const unsigned char hid_keyboard[256] = { | 37 | static const unsigned char hid_keyboard[256] = { |
@@ -192,6 +190,7 @@ static int hidinput_setkeycode(struct input_dev *dev, | |||
192 | return -EINVAL; | 190 | return -EINVAL; |
193 | } | 191 | } |
194 | 192 | ||
193 | |||
195 | /** | 194 | /** |
196 | * hidinput_calc_abs_res - calculate an absolute axis resolution | 195 | * hidinput_calc_abs_res - calculate an absolute axis resolution |
197 | * @field: the HID report field to calculate resolution for | 196 | * @field: the HID report field to calculate resolution for |
@@ -207,7 +206,7 @@ static int hidinput_setkeycode(struct input_dev *dev, | |||
207 | * Only exponent 1 length units are processed. Centimeters and inches are | 206 | * Only exponent 1 length units are processed. Centimeters and inches are |
208 | * converted to millimeters. Degrees are converted to radians. | 207 | * converted to millimeters. Degrees are converted to radians. |
209 | */ | 208 | */ |
210 | __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) | 209 | static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) |
211 | { | 210 | { |
212 | __s32 unit_exponent = field->unit_exponent; | 211 | __s32 unit_exponent = field->unit_exponent; |
213 | __s32 logical_extents = field->logical_maximum - | 212 | __s32 logical_extents = field->logical_maximum - |
@@ -224,42 +223,21 @@ __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) | |||
224 | * Verify and convert units. | 223 | * Verify and convert units. |
225 | * See HID specification v1.11 6.2.2.7 Global Items for unit decoding | 224 | * See HID specification v1.11 6.2.2.7 Global Items for unit decoding |
226 | */ | 225 | */ |
227 | switch (code) { | 226 | if (code == ABS_X || code == ABS_Y || code == ABS_Z) { |
228 | case ABS_X: | 227 | if (field->unit == 0x11) { /* If centimeters */ |
229 | case ABS_Y: | ||
230 | case ABS_Z: | ||
231 | case ABS_MT_POSITION_X: | ||
232 | case ABS_MT_POSITION_Y: | ||
233 | case ABS_MT_TOOL_X: | ||
234 | case ABS_MT_TOOL_Y: | ||
235 | case ABS_MT_TOUCH_MAJOR: | ||
236 | case ABS_MT_TOUCH_MINOR: | ||
237 | if (field->unit & 0xffffff00) /* Not a length */ | ||
238 | return 0; | ||
239 | unit_exponent += hid_snto32(field->unit >> 4, 4) - 1; | ||
240 | switch (field->unit & 0xf) { | ||
241 | case 0x1: /* If centimeters */ | ||
242 | /* Convert to millimeters */ | 228 | /* Convert to millimeters */ |
243 | unit_exponent += 1; | 229 | unit_exponent += 1; |
244 | break; | 230 | } else if (field->unit == 0x13) { /* If inches */ |
245 | case 0x3: /* If inches */ | ||
246 | /* Convert to millimeters */ | 231 | /* Convert to millimeters */ |
247 | prev = physical_extents; | 232 | prev = physical_extents; |
248 | physical_extents *= 254; | 233 | physical_extents *= 254; |
249 | if (physical_extents < prev) | 234 | if (physical_extents < prev) |
250 | return 0; | 235 | return 0; |
251 | unit_exponent -= 1; | 236 | unit_exponent -= 1; |
252 | break; | 237 | } else { |
253 | default: | ||
254 | return 0; | 238 | return 0; |
255 | } | 239 | } |
256 | break; | 240 | } else if (code == ABS_RX || code == ABS_RY || code == ABS_RZ) { |
257 | |||
258 | case ABS_RX: | ||
259 | case ABS_RY: | ||
260 | case ABS_RZ: | ||
261 | case ABS_TILT_X: | ||
262 | case ABS_TILT_Y: | ||
263 | if (field->unit == 0x14) { /* If degrees */ | 241 | if (field->unit == 0x14) { /* If degrees */ |
264 | /* Convert to radians */ | 242 | /* Convert to radians */ |
265 | prev = logical_extents; | 243 | prev = logical_extents; |
@@ -270,9 +248,7 @@ __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) | |||
270 | } else if (field->unit != 0x12) { /* If not radians */ | 248 | } else if (field->unit != 0x12) { /* If not radians */ |
271 | return 0; | 249 | return 0; |
272 | } | 250 | } |
273 | break; | 251 | } else { |
274 | |||
275 | default: | ||
276 | return 0; | 252 | return 0; |
277 | } | 253 | } |
278 | 254 | ||
@@ -292,178 +268,9 @@ __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) | |||
292 | } | 268 | } |
293 | 269 | ||
294 | /* Calculate resolution */ | 270 | /* Calculate resolution */ |
295 | return DIV_ROUND_CLOSEST(logical_extents, physical_extents); | 271 | return logical_extents / physical_extents; |
296 | } | ||
297 | EXPORT_SYMBOL_GPL(hidinput_calc_abs_res); | ||
298 | |||
299 | #ifdef CONFIG_HID_BATTERY_STRENGTH | ||
300 | static enum power_supply_property hidinput_battery_props[] = { | ||
301 | POWER_SUPPLY_PROP_PRESENT, | ||
302 | POWER_SUPPLY_PROP_ONLINE, | ||
303 | POWER_SUPPLY_PROP_CAPACITY, | ||
304 | POWER_SUPPLY_PROP_MODEL_NAME, | ||
305 | POWER_SUPPLY_PROP_STATUS, | ||
306 | POWER_SUPPLY_PROP_SCOPE, | ||
307 | }; | ||
308 | |||
309 | #define HID_BATTERY_QUIRK_PERCENT (1 << 0) /* always reports percent */ | ||
310 | #define HID_BATTERY_QUIRK_FEATURE (1 << 1) /* ask for feature report */ | ||
311 | |||
312 | static const struct hid_device_id hid_battery_quirks[] = { | ||
313 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | ||
314 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), | ||
315 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, | ||
316 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | ||
317 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), | ||
318 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, | ||
319 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | ||
320 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI), | ||
321 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, | ||
322 | {} | ||
323 | }; | ||
324 | |||
325 | static unsigned find_battery_quirk(struct hid_device *hdev) | ||
326 | { | ||
327 | unsigned quirks = 0; | ||
328 | const struct hid_device_id *match; | ||
329 | |||
330 | match = hid_match_id(hdev, hid_battery_quirks); | ||
331 | if (match != NULL) | ||
332 | quirks = match->driver_data; | ||
333 | |||
334 | return quirks; | ||
335 | } | 272 | } |
336 | 273 | ||
337 | static int hidinput_get_battery_property(struct power_supply *psy, | ||
338 | enum power_supply_property prop, | ||
339 | union power_supply_propval *val) | ||
340 | { | ||
341 | struct hid_device *dev = container_of(psy, struct hid_device, battery); | ||
342 | int ret = 0; | ||
343 | __u8 buf[2] = {}; | ||
344 | |||
345 | switch (prop) { | ||
346 | case POWER_SUPPLY_PROP_PRESENT: | ||
347 | case POWER_SUPPLY_PROP_ONLINE: | ||
348 | val->intval = 1; | ||
349 | break; | ||
350 | |||
351 | case POWER_SUPPLY_PROP_CAPACITY: | ||
352 | ret = dev->hid_get_raw_report(dev, dev->battery_report_id, | ||
353 | buf, sizeof(buf), | ||
354 | dev->battery_report_type); | ||
355 | |||
356 | if (ret != 2) { | ||
357 | if (ret >= 0) | ||
358 | ret = -EINVAL; | ||
359 | break; | ||
360 | } | ||
361 | |||
362 | if (dev->battery_min < dev->battery_max && | ||
363 | buf[1] >= dev->battery_min && | ||
364 | buf[1] <= dev->battery_max) | ||
365 | val->intval = (100 * (buf[1] - dev->battery_min)) / | ||
366 | (dev->battery_max - dev->battery_min); | ||
367 | break; | ||
368 | |||
369 | case POWER_SUPPLY_PROP_MODEL_NAME: | ||
370 | val->strval = dev->name; | ||
371 | break; | ||
372 | |||
373 | case POWER_SUPPLY_PROP_STATUS: | ||
374 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; | ||
375 | break; | ||
376 | |||
377 | case POWER_SUPPLY_PROP_SCOPE: | ||
378 | val->intval = POWER_SUPPLY_SCOPE_DEVICE; | ||
379 | break; | ||
380 | |||
381 | default: | ||
382 | ret = -EINVAL; | ||
383 | break; | ||
384 | } | ||
385 | |||
386 | return ret; | ||
387 | } | ||
388 | |||
389 | static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type, struct hid_field *field) | ||
390 | { | ||
391 | struct power_supply *battery = &dev->battery; | ||
392 | int ret; | ||
393 | unsigned quirks; | ||
394 | s32 min, max; | ||
395 | |||
396 | if (field->usage->hid != HID_DC_BATTERYSTRENGTH) | ||
397 | return false; /* no match */ | ||
398 | |||
399 | if (battery->name != NULL) | ||
400 | goto out; /* already initialized? */ | ||
401 | |||
402 | battery->name = kasprintf(GFP_KERNEL, "hid-%s-battery", dev->uniq); | ||
403 | if (battery->name == NULL) | ||
404 | goto out; | ||
405 | |||
406 | battery->type = POWER_SUPPLY_TYPE_BATTERY; | ||
407 | battery->properties = hidinput_battery_props; | ||
408 | battery->num_properties = ARRAY_SIZE(hidinput_battery_props); | ||
409 | battery->use_for_apm = 0; | ||
410 | battery->get_property = hidinput_get_battery_property; | ||
411 | |||
412 | quirks = find_battery_quirk(dev); | ||
413 | |||
414 | hid_dbg(dev, "device %x:%x:%x %d quirks %d\n", | ||
415 | dev->bus, dev->vendor, dev->product, dev->version, quirks); | ||
416 | |||
417 | min = field->logical_minimum; | ||
418 | max = field->logical_maximum; | ||
419 | |||
420 | if (quirks & HID_BATTERY_QUIRK_PERCENT) { | ||
421 | min = 0; | ||
422 | max = 100; | ||
423 | } | ||
424 | |||
425 | if (quirks & HID_BATTERY_QUIRK_FEATURE) | ||
426 | report_type = HID_FEATURE_REPORT; | ||
427 | |||
428 | dev->battery_min = min; | ||
429 | dev->battery_max = max; | ||
430 | dev->battery_report_type = report_type; | ||
431 | dev->battery_report_id = field->report->id; | ||
432 | |||
433 | ret = power_supply_register(&dev->dev, battery); | ||
434 | if (ret != 0) { | ||
435 | hid_warn(dev, "can't register power supply: %d\n", ret); | ||
436 | kfree(battery->name); | ||
437 | battery->name = NULL; | ||
438 | } | ||
439 | |||
440 | power_supply_powers(battery, &dev->dev); | ||
441 | |||
442 | out: | ||
443 | return true; | ||
444 | } | ||
445 | |||
446 | static void hidinput_cleanup_battery(struct hid_device *dev) | ||
447 | { | ||
448 | if (!dev->battery.name) | ||
449 | return; | ||
450 | |||
451 | power_supply_unregister(&dev->battery); | ||
452 | kfree(dev->battery.name); | ||
453 | dev->battery.name = NULL; | ||
454 | } | ||
455 | #else /* !CONFIG_HID_BATTERY_STRENGTH */ | ||
456 | static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type, | ||
457 | struct hid_field *field) | ||
458 | { | ||
459 | return false; | ||
460 | } | ||
461 | |||
462 | static void hidinput_cleanup_battery(struct hid_device *dev) | ||
463 | { | ||
464 | } | ||
465 | #endif /* CONFIG_HID_BATTERY_STRENGTH */ | ||
466 | |||
467 | static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, | 274 | static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, |
468 | struct hid_usage *usage) | 275 | struct hid_usage *usage) |
469 | { | 276 | { |
@@ -517,14 +324,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
517 | if (code <= 0xf) | 324 | if (code <= 0xf) |
518 | code += BTN_JOYSTICK; | 325 | code += BTN_JOYSTICK; |
519 | else | 326 | else |
520 | code += BTN_TRIGGER_HAPPY - 0x10; | 327 | code += BTN_TRIGGER_HAPPY; |
521 | break; | ||
522 | case HID_GD_GAMEPAD: | ||
523 | if (code <= 0xf) | ||
524 | code += BTN_GAMEPAD; | ||
525 | else | ||
526 | code += BTN_TRIGGER_HAPPY - 0x10; | ||
527 | break; | 328 | break; |
329 | case HID_GD_GAMEPAD: code += BTN_GAMEPAD; break; | ||
528 | default: | 330 | default: |
529 | switch (field->physical) { | 331 | switch (field->physical) { |
530 | case HID_GD_MOUSE: | 332 | case HID_GD_MOUSE: |
@@ -657,14 +459,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
657 | map_key_clear(BTN_TOOL_RUBBER); | 459 | map_key_clear(BTN_TOOL_RUBBER); |
658 | break; | 460 | break; |
659 | 461 | ||
660 | case 0x3d: /* X Tilt */ | ||
661 | map_abs_clear(ABS_TILT_X); | ||
662 | break; | ||
663 | |||
664 | case 0x3e: /* Y Tilt */ | ||
665 | map_abs_clear(ABS_TILT_Y); | ||
666 | break; | ||
667 | |||
668 | case 0x33: /* Touch */ | 462 | case 0x33: /* Touch */ |
669 | case 0x42: /* TipSwitch */ | 463 | case 0x42: /* TipSwitch */ |
670 | case 0x43: /* TipSwitch2 */ | 464 | case 0x43: /* TipSwitch2 */ |
@@ -831,13 +625,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
831 | } | 625 | } |
832 | break; | 626 | break; |
833 | 627 | ||
834 | case HID_UP_GENDEVCTRLS: | ||
835 | if (hidinput_setup_battery(device, HID_INPUT_REPORT, field)) | ||
836 | goto ignore; | ||
837 | else | ||
838 | goto unknown; | ||
839 | break; | ||
840 | |||
841 | case HID_UP_HPVENDOR: /* Reported on a Dutch layout HP5308 */ | 628 | case HID_UP_HPVENDOR: /* Reported on a Dutch layout HP5308 */ |
842 | set_bit(EV_REP, input->evbit); | 629 | set_bit(EV_REP, input->evbit); |
843 | switch (usage->hid & HID_USAGE) { | 630 | switch (usage->hid & HID_USAGE) { |
@@ -857,15 +644,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
857 | } | 644 | } |
858 | break; | 645 | break; |
859 | 646 | ||
860 | case HID_UP_HPVENDOR2: | ||
861 | set_bit(EV_REP, input->evbit); | ||
862 | switch (usage->hid & HID_USAGE) { | ||
863 | case 0x003: map_key_clear(KEY_BRIGHTNESSDOWN); break; | ||
864 | case 0x004: map_key_clear(KEY_BRIGHTNESSUP); break; | ||
865 | default: goto ignore; | ||
866 | } | ||
867 | break; | ||
868 | |||
869 | case HID_UP_MSVENDOR: | 647 | case HID_UP_MSVENDOR: |
870 | goto ignore; | 648 | goto ignore; |
871 | 649 | ||
@@ -1040,17 +818,6 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct | |||
1040 | return; | 818 | return; |
1041 | } | 819 | } |
1042 | 820 | ||
1043 | /* | ||
1044 | * Ignore out-of-range values as per HID specification, | ||
1045 | * section 5.10 and 6.2.25 | ||
1046 | */ | ||
1047 | if ((field->flags & HID_MAIN_ITEM_VARIABLE) && | ||
1048 | (value < field->logical_minimum || | ||
1049 | value > field->logical_maximum)) { | ||
1050 | dbg_hid("Ignoring out-of-range value %x\n", value); | ||
1051 | return; | ||
1052 | } | ||
1053 | |||
1054 | /* report the usage code as scancode if the key status has changed */ | 821 | /* report the usage code as scancode if the key status has changed */ |
1055 | if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value) | 822 | if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value) |
1056 | input_event(input, EV_MSC, MSC_SCAN, usage->hid); | 823 | input_event(input, EV_MSC, MSC_SCAN, usage->hid); |
@@ -1090,48 +857,6 @@ int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int | |||
1090 | } | 857 | } |
1091 | EXPORT_SYMBOL_GPL(hidinput_find_field); | 858 | EXPORT_SYMBOL_GPL(hidinput_find_field); |
1092 | 859 | ||
1093 | struct hid_field *hidinput_get_led_field(struct hid_device *hid) | ||
1094 | { | ||
1095 | struct hid_report *report; | ||
1096 | struct hid_field *field; | ||
1097 | int i, j; | ||
1098 | |||
1099 | list_for_each_entry(report, | ||
1100 | &hid->report_enum[HID_OUTPUT_REPORT].report_list, | ||
1101 | list) { | ||
1102 | for (i = 0; i < report->maxfield; i++) { | ||
1103 | field = report->field[i]; | ||
1104 | for (j = 0; j < field->maxusage; j++) | ||
1105 | if (field->usage[j].type == EV_LED) | ||
1106 | return field; | ||
1107 | } | ||
1108 | } | ||
1109 | return NULL; | ||
1110 | } | ||
1111 | EXPORT_SYMBOL_GPL(hidinput_get_led_field); | ||
1112 | |||
1113 | unsigned int hidinput_count_leds(struct hid_device *hid) | ||
1114 | { | ||
1115 | struct hid_report *report; | ||
1116 | struct hid_field *field; | ||
1117 | int i, j; | ||
1118 | unsigned int count = 0; | ||
1119 | |||
1120 | list_for_each_entry(report, | ||
1121 | &hid->report_enum[HID_OUTPUT_REPORT].report_list, | ||
1122 | list) { | ||
1123 | for (i = 0; i < report->maxfield; i++) { | ||
1124 | field = report->field[i]; | ||
1125 | for (j = 0; j < field->maxusage; j++) | ||
1126 | if (field->usage[j].type == EV_LED && | ||
1127 | field->value[j]) | ||
1128 | count += 1; | ||
1129 | } | ||
1130 | } | ||
1131 | return count; | ||
1132 | } | ||
1133 | EXPORT_SYMBOL_GPL(hidinput_count_leds); | ||
1134 | |||
1135 | static int hidinput_open(struct input_dev *dev) | 860 | static int hidinput_open(struct input_dev *dev) |
1136 | { | 861 | { |
1137 | struct hid_device *hid = input_get_drvdata(dev); | 862 | struct hid_device *hid = input_get_drvdata(dev); |
@@ -1153,49 +878,15 @@ static void report_features(struct hid_device *hid) | |||
1153 | struct hid_report *rep; | 878 | struct hid_report *rep; |
1154 | int i, j; | 879 | int i, j; |
1155 | 880 | ||
881 | if (!drv->feature_mapping) | ||
882 | return; | ||
883 | |||
1156 | rep_enum = &hid->report_enum[HID_FEATURE_REPORT]; | 884 | rep_enum = &hid->report_enum[HID_FEATURE_REPORT]; |
1157 | list_for_each_entry(rep, &rep_enum->report_list, list) | 885 | list_for_each_entry(rep, &rep_enum->report_list, list) |
1158 | for (i = 0; i < rep->maxfield; i++) | 886 | for (i = 0; i < rep->maxfield; i++) |
1159 | for (j = 0; j < rep->field[i]->maxusage; j++) { | 887 | for (j = 0; j < rep->field[i]->maxusage; j++) |
1160 | /* Verify if Battery Strength feature is available */ | 888 | drv->feature_mapping(hid, rep->field[i], |
1161 | hidinput_setup_battery(hid, HID_FEATURE_REPORT, rep->field[i]); | 889 | rep->field[i]->usage + j); |
1162 | |||
1163 | if (drv->feature_mapping) | ||
1164 | drv->feature_mapping(hid, rep->field[i], | ||
1165 | rep->field[i]->usage + j); | ||
1166 | } | ||
1167 | } | ||
1168 | |||
1169 | static struct hid_input *hidinput_allocate(struct hid_device *hid) | ||
1170 | { | ||
1171 | struct hid_input *hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL); | ||
1172 | struct input_dev *input_dev = input_allocate_device(); | ||
1173 | if (!hidinput || !input_dev) { | ||
1174 | kfree(hidinput); | ||
1175 | input_free_device(input_dev); | ||
1176 | hid_err(hid, "Out of memory during hid input probe\n"); | ||
1177 | return NULL; | ||
1178 | } | ||
1179 | |||
1180 | input_set_drvdata(input_dev, hid); | ||
1181 | input_dev->event = hid->ll_driver->hidinput_input_event; | ||
1182 | input_dev->open = hidinput_open; | ||
1183 | input_dev->close = hidinput_close; | ||
1184 | input_dev->setkeycode = hidinput_setkeycode; | ||
1185 | input_dev->getkeycode = hidinput_getkeycode; | ||
1186 | |||
1187 | input_dev->name = hid->name; | ||
1188 | input_dev->phys = hid->phys; | ||
1189 | input_dev->uniq = hid->uniq; | ||
1190 | input_dev->id.bustype = hid->bus; | ||
1191 | input_dev->id.vendor = hid->vendor; | ||
1192 | input_dev->id.product = hid->product; | ||
1193 | input_dev->id.version = hid->version; | ||
1194 | input_dev->dev.parent = hid->dev.parent; | ||
1195 | hidinput->input = input_dev; | ||
1196 | list_add_tail(&hidinput->list, &hid->inputs); | ||
1197 | |||
1198 | return hidinput; | ||
1199 | } | 890 | } |
1200 | 891 | ||
1201 | /* | 892 | /* |
@@ -1206,9 +897,9 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid) | |||
1206 | 897 | ||
1207 | int hidinput_connect(struct hid_device *hid, unsigned int force) | 898 | int hidinput_connect(struct hid_device *hid, unsigned int force) |
1208 | { | 899 | { |
1209 | struct hid_driver *drv = hid->driver; | ||
1210 | struct hid_report *report; | 900 | struct hid_report *report; |
1211 | struct hid_input *hidinput = NULL; | 901 | struct hid_input *hidinput = NULL; |
902 | struct input_dev *input_dev; | ||
1212 | int i, j, k; | 903 | int i, j, k; |
1213 | 904 | ||
1214 | INIT_LIST_HEAD(&hid->inputs); | 905 | INIT_LIST_HEAD(&hid->inputs); |
@@ -1239,9 +930,33 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) | |||
1239 | continue; | 930 | continue; |
1240 | 931 | ||
1241 | if (!hidinput) { | 932 | if (!hidinput) { |
1242 | hidinput = hidinput_allocate(hid); | 933 | hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL); |
1243 | if (!hidinput) | 934 | input_dev = input_allocate_device(); |
935 | if (!hidinput || !input_dev) { | ||
936 | kfree(hidinput); | ||
937 | input_free_device(input_dev); | ||
938 | hid_err(hid, "Out of memory during hid input probe\n"); | ||
1244 | goto out_unwind; | 939 | goto out_unwind; |
940 | } | ||
941 | |||
942 | input_set_drvdata(input_dev, hid); | ||
943 | input_dev->event = | ||
944 | hid->ll_driver->hidinput_input_event; | ||
945 | input_dev->open = hidinput_open; | ||
946 | input_dev->close = hidinput_close; | ||
947 | input_dev->setkeycode = hidinput_setkeycode; | ||
948 | input_dev->getkeycode = hidinput_getkeycode; | ||
949 | |||
950 | input_dev->name = hid->name; | ||
951 | input_dev->phys = hid->phys; | ||
952 | input_dev->uniq = hid->uniq; | ||
953 | input_dev->id.bustype = hid->bus; | ||
954 | input_dev->id.vendor = hid->vendor; | ||
955 | input_dev->id.product = hid->product; | ||
956 | input_dev->id.version = hid->version; | ||
957 | input_dev->dev.parent = hid->dev.parent; | ||
958 | hidinput->input = input_dev; | ||
959 | list_add_tail(&hidinput->list, &hid->inputs); | ||
1245 | } | 960 | } |
1246 | 961 | ||
1247 | for (i = 0; i < report->maxfield; i++) | 962 | for (i = 0; i < report->maxfield; i++) |
@@ -1256,8 +971,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) | |||
1256 | * UGCI) cram a lot of unrelated inputs into the | 971 | * UGCI) cram a lot of unrelated inputs into the |
1257 | * same interface. */ | 972 | * same interface. */ |
1258 | hidinput->report = report; | 973 | hidinput->report = report; |
1259 | if (drv->input_configured) | 974 | if (hid->driver->input_register && |
1260 | drv->input_configured(hid, hidinput); | 975 | hid->driver->input_register(hid, hidinput)) |
976 | goto out_cleanup; | ||
1261 | if (input_register_device(hidinput->input)) | 977 | if (input_register_device(hidinput->input)) |
1262 | goto out_cleanup; | 978 | goto out_cleanup; |
1263 | hidinput = NULL; | 979 | hidinput = NULL; |
@@ -1265,12 +981,12 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) | |||
1265 | } | 981 | } |
1266 | } | 982 | } |
1267 | 983 | ||
1268 | if (hidinput) { | 984 | if (hidinput && hid->driver->input_register && |
1269 | if (drv->input_configured) | 985 | hid->driver->input_register(hid, hidinput)) |
1270 | drv->input_configured(hid, hidinput); | 986 | goto out_cleanup; |
1271 | if (input_register_device(hidinput->input)) | 987 | |
1272 | goto out_cleanup; | 988 | if (hidinput && input_register_device(hidinput->input)) |
1273 | } | 989 | goto out_cleanup; |
1274 | 990 | ||
1275 | return 0; | 991 | return 0; |
1276 | 992 | ||
@@ -1290,8 +1006,6 @@ void hidinput_disconnect(struct hid_device *hid) | |||
1290 | { | 1006 | { |
1291 | struct hid_input *hidinput, *next; | 1007 | struct hid_input *hidinput, *next; |
1292 | 1008 | ||
1293 | hidinput_cleanup_battery(hid); | ||
1294 | |||
1295 | list_for_each_entry_safe(hidinput, next, &hid->inputs, list) { | 1009 | list_for_each_entry_safe(hidinput, next, &hid->inputs, list) { |
1296 | list_del(&hidinput->list); | 1010 | list_del(&hidinput->list); |
1297 | input_unregister_device(hidinput->input); | 1011 | input_unregister_device(hidinput->input); |