Commit 20c55f25 authored by Nicolas Boichat's avatar Nicolas Boichat Committed by Jiri Kosina

HID: google: Detect base folded usage instead of hard-coding whiskers

Some other hammer-like device will emit a similar code, let's look for
the folded event in HID usage table, instead of hard-coding whiskers
in many places.
Signed-off-by: default avatarNicolas Boichat <drinkcat@chromium.org>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent b543db46
...@@ -370,7 +370,7 @@ static void hammer_unregister_leds(struct hid_device *hdev) ...@@ -370,7 +370,7 @@ static void hammer_unregister_leds(struct hid_device *hdev)
#define HID_UP_GOOGLEVENDOR 0xffd10000 #define HID_UP_GOOGLEVENDOR 0xffd10000
#define HID_VD_KBD_FOLDED 0x00000019 #define HID_VD_KBD_FOLDED 0x00000019
#define WHISKERS_KBD_FOLDED (HID_UP_GOOGLEVENDOR | HID_VD_KBD_FOLDED) #define HID_USAGE_KBD_FOLDED (HID_UP_GOOGLEVENDOR | HID_VD_KBD_FOLDED)
/* HID usage for keyboard backlight (Alphanumeric display brightness) */ /* HID usage for keyboard backlight (Alphanumeric display brightness) */
#define HID_AD_BRIGHTNESS 0x00140046 #define HID_AD_BRIGHTNESS 0x00140046
...@@ -380,8 +380,7 @@ static int hammer_input_mapping(struct hid_device *hdev, struct hid_input *hi, ...@@ -380,8 +380,7 @@ static int hammer_input_mapping(struct hid_device *hdev, struct hid_input *hi,
struct hid_usage *usage, struct hid_usage *usage,
unsigned long **bit, int *max) unsigned long **bit, int *max)
{ {
if (hdev->product == USB_DEVICE_ID_GOOGLE_WHISKERS && if (usage->hid == HID_USAGE_KBD_FOLDED) {
usage->hid == WHISKERS_KBD_FOLDED) {
/* /*
* We do not want to have this usage mapped as it will get * We do not want to have this usage mapped as it will get
* mixed in with "base attached" signal and delivered over * mixed in with "base attached" signal and delivered over
...@@ -398,8 +397,7 @@ static int hammer_event(struct hid_device *hid, struct hid_field *field, ...@@ -398,8 +397,7 @@ static int hammer_event(struct hid_device *hid, struct hid_field *field,
{ {
unsigned long flags; unsigned long flags;
if (hid->product == USB_DEVICE_ID_GOOGLE_WHISKERS && if (usage->hid == HID_USAGE_KBD_FOLDED) {
usage->hid == WHISKERS_KBD_FOLDED) {
spin_lock_irqsave(&cbas_ec_lock, flags); spin_lock_irqsave(&cbas_ec_lock, flags);
/* /*
...@@ -424,33 +422,22 @@ static int hammer_event(struct hid_device *hid, struct hid_field *field, ...@@ -424,33 +422,22 @@ static int hammer_event(struct hid_device *hid, struct hid_field *field,
return 0; return 0;
} }
static bool hammer_is_keyboard_interface(struct hid_device *hdev) static bool hammer_has_usage(struct hid_device *hdev, unsigned int report_type,
unsigned application, unsigned usage)
{ {
struct hid_report_enum *re = &hdev->report_enum[HID_INPUT_REPORT]; struct hid_report_enum *re = &hdev->report_enum[report_type];
struct hid_report *report;
list_for_each_entry(report, &re->report_list, list)
if (report->application == HID_GD_KEYBOARD)
return true;
return false;
}
static bool hammer_has_backlight_control(struct hid_device *hdev)
{
struct hid_report_enum *re = &hdev->report_enum[HID_OUTPUT_REPORT];
struct hid_report *report; struct hid_report *report;
int i, j; int i, j;
list_for_each_entry(report, &re->report_list, list) { list_for_each_entry(report, &re->report_list, list) {
if (report->application != HID_GD_KEYBOARD) if (report->application != application)
continue; continue;
for (i = 0; i < report->maxfield; i++) { for (i = 0; i < report->maxfield; i++) {
struct hid_field *field = report->field[i]; struct hid_field *field = report->field[i];
for (j = 0; j < field->maxusage; j++) for (j = 0; j < field->maxusage; j++)
if (field->usage[j].hid == HID_AD_BRIGHTNESS) if (field->usage[j].hid == usage)
return true; return true;
} }
} }
...@@ -458,6 +445,18 @@ static bool hammer_has_backlight_control(struct hid_device *hdev) ...@@ -458,6 +445,18 @@ static bool hammer_has_backlight_control(struct hid_device *hdev)
return false; return false;
} }
static bool hammer_has_folded_event(struct hid_device *hdev)
{
return hammer_has_usage(hdev, HID_INPUT_REPORT,
HID_GD_KEYBOARD, HID_USAGE_KBD_FOLDED);
}
static bool hammer_has_backlight_control(struct hid_device *hdev)
{
return hammer_has_usage(hdev, HID_OUTPUT_REPORT,
HID_GD_KEYBOARD, HID_AD_BRIGHTNESS);
}
static int hammer_probe(struct hid_device *hdev, static int hammer_probe(struct hid_device *hdev,
const struct hid_device_id *id) const struct hid_device_id *id)
{ {
...@@ -473,12 +472,11 @@ static int hammer_probe(struct hid_device *hdev, ...@@ -473,12 +472,11 @@ static int hammer_probe(struct hid_device *hdev,
/* /*
* We always want to poll for, and handle tablet mode events from * We always want to poll for, and handle tablet mode events from
* Whiskers, even when nobody has opened the input device. This also * devices that have folded usage, even when nobody has opened the input
* prevents the hid core from dropping early tablet mode events from * device. This also prevents the hid core from dropping early tablet
* the device. * mode events from the device.
*/ */
if (hdev->product == USB_DEVICE_ID_GOOGLE_WHISKERS && if (hammer_has_folded_event(hdev)) {
hammer_is_keyboard_interface(hdev)) {
hdev->quirks |= HID_QUIRK_ALWAYS_POLL; hdev->quirks |= HID_QUIRK_ALWAYS_POLL;
error = hid_hw_open(hdev); error = hid_hw_open(hdev);
if (error) if (error)
...@@ -500,8 +498,7 @@ static void hammer_remove(struct hid_device *hdev) ...@@ -500,8 +498,7 @@ static void hammer_remove(struct hid_device *hdev)
{ {
unsigned long flags; unsigned long flags;
if (hdev->product == USB_DEVICE_ID_GOOGLE_WHISKERS && if (hammer_has_folded_event(hdev)) {
hammer_is_keyboard_interface(hdev)) {
hid_hw_close(hdev); hid_hw_close(hdev);
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment