mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-23 23:32:14 +00:00
Merge branches 'for-4.10/asus', 'for-4.10/cp2112', 'for-4.10/i2c-hid-nopower', 'for-4.10/intel-ish', 'for-4.10/mayflash', 'for-4.10/microsoft-surface-3', 'for-4.10/multitouch', 'for-4.10/sony', 'for-4.10/udraw-ps3', 'for-4.10/upstream' and 'for-4.10/wacom/generic' into for-linus
This commit is contained in:
parent
9ce12d8be1
13c28b0297
8cd16166b0
608ad1848b
f8690450f3
b897f6db3a
594312b88b
de66a1a04c
9c5dcd7231
c60fa555b1
c9cfb2aca2
commit
96e132ebc0
25 changed files with 2145 additions and 478 deletions
|
@ -253,6 +253,7 @@ __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)
|
|||
case ABS_RX:
|
||||
case ABS_RY:
|
||||
case ABS_RZ:
|
||||
case ABS_WHEEL:
|
||||
case ABS_TILT_X:
|
||||
case ABS_TILT_Y:
|
||||
if (field->unit == 0x14) { /* If degrees */
|
||||
|
@ -1468,6 +1469,31 @@ static void hidinput_cleanup_hidinput(struct hid_device *hid,
|
|||
kfree(hidinput);
|
||||
}
|
||||
|
||||
static struct hid_input *hidinput_match(struct hid_report *report)
|
||||
{
|
||||
struct hid_device *hid = report->device;
|
||||
struct hid_input *hidinput;
|
||||
|
||||
list_for_each_entry(hidinput, &hid->inputs, list) {
|
||||
if (hidinput->report &&
|
||||
hidinput->report->id == report->id)
|
||||
return hidinput;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void hidinput_configure_usages(struct hid_input *hidinput,
|
||||
struct hid_report *report)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < report->maxfield; i++)
|
||||
for (j = 0; j < report->field[i]->maxusage; j++)
|
||||
hidinput_configure_usage(hidinput, report->field[i],
|
||||
report->field[i]->usage + j);
|
||||
}
|
||||
|
||||
/*
|
||||
* Register the input device; print a message.
|
||||
* Configure the input layer interface
|
||||
|
@ -1478,8 +1504,8 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
|
|||
{
|
||||
struct hid_driver *drv = hid->driver;
|
||||
struct hid_report *report;
|
||||
struct hid_input *hidinput = NULL;
|
||||
int i, j, k;
|
||||
struct hid_input *next, *hidinput = NULL;
|
||||
int i, k;
|
||||
|
||||
INIT_LIST_HEAD(&hid->inputs);
|
||||
INIT_WORK(&hid->led_work, hidinput_led_worker);
|
||||
|
@ -1509,43 +1535,40 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
|
|||
if (!report->maxfield)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Find the previous hidinput report attached
|
||||
* to this report id.
|
||||
*/
|
||||
if (hid->quirks & HID_QUIRK_MULTI_INPUT)
|
||||
hidinput = hidinput_match(report);
|
||||
|
||||
if (!hidinput) {
|
||||
hidinput = hidinput_allocate(hid);
|
||||
if (!hidinput)
|
||||
goto out_unwind;
|
||||
}
|
||||
|
||||
for (i = 0; i < report->maxfield; i++)
|
||||
for (j = 0; j < report->field[i]->maxusage; j++)
|
||||
hidinput_configure_usage(hidinput, report->field[i],
|
||||
report->field[i]->usage + j);
|
||||
hidinput_configure_usages(hidinput, report);
|
||||
|
||||
if ((hid->quirks & HID_QUIRK_NO_EMPTY_INPUT) &&
|
||||
!hidinput_has_been_populated(hidinput))
|
||||
continue;
|
||||
|
||||
if (hid->quirks & HID_QUIRK_MULTI_INPUT) {
|
||||
/* This will leave hidinput NULL, so that it
|
||||
* allocates another one if we have more inputs on
|
||||
* the same interface. Some devices (e.g. Happ's
|
||||
* UGCI) cram a lot of unrelated inputs into the
|
||||
* same interface. */
|
||||
if (hid->quirks & HID_QUIRK_MULTI_INPUT)
|
||||
hidinput->report = report;
|
||||
if (drv->input_configured &&
|
||||
drv->input_configured(hid, hidinput))
|
||||
goto out_cleanup;
|
||||
if (input_register_device(hidinput->input))
|
||||
goto out_cleanup;
|
||||
hidinput = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hidinput && (hid->quirks & HID_QUIRK_NO_EMPTY_INPUT) &&
|
||||
!hidinput_has_been_populated(hidinput)) {
|
||||
/* no need to register an input device not populated */
|
||||
hidinput_cleanup_hidinput(hid, hidinput);
|
||||
hidinput = NULL;
|
||||
list_for_each_entry_safe(hidinput, next, &hid->inputs, list) {
|
||||
if ((hid->quirks & HID_QUIRK_NO_EMPTY_INPUT) &&
|
||||
!hidinput_has_been_populated(hidinput)) {
|
||||
/* no need to register an input device not populated */
|
||||
hidinput_cleanup_hidinput(hid, hidinput);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (drv->input_configured &&
|
||||
drv->input_configured(hid, hidinput))
|
||||
goto out_unwind;
|
||||
if (input_register_device(hidinput->input))
|
||||
goto out_unwind;
|
||||
hidinput->registered = true;
|
||||
}
|
||||
|
||||
if (list_empty(&hid->inputs)) {
|
||||
|
@ -1553,20 +1576,8 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
|
|||
goto out_unwind;
|
||||
}
|
||||
|
||||
if (hidinput) {
|
||||
if (drv->input_configured &&
|
||||
drv->input_configured(hid, hidinput))
|
||||
goto out_cleanup;
|
||||
if (input_register_device(hidinput->input))
|
||||
goto out_cleanup;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out_cleanup:
|
||||
list_del(&hidinput->list);
|
||||
input_free_device(hidinput->input);
|
||||
kfree(hidinput);
|
||||
out_unwind:
|
||||
/* unwind the ones we already registered */
|
||||
hidinput_disconnect(hid);
|
||||
|
@ -1583,7 +1594,10 @@ void hidinput_disconnect(struct hid_device *hid)
|
|||
|
||||
list_for_each_entry_safe(hidinput, next, &hid->inputs, list) {
|
||||
list_del(&hidinput->list);
|
||||
input_unregister_device(hidinput->input);
|
||||
if (hidinput->registered)
|
||||
input_unregister_device(hidinput->input);
|
||||
else
|
||||
input_free_device(hidinput->input);
|
||||
kfree(hidinput);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue