HID: wacom: generic: Add support for battery status on pen and pad interfaces
authorJason Gerecke <killertofu@gmail.com>
Thu, 20 Oct 2016 01:03:52 +0000 (18:03 -0700)
committerJiri Kosina <jkosina@suse.cz>
Thu, 20 Oct 2016 07:54:00 +0000 (09:54 +0200)
Adds support for usages that may appear on the pen or pad interface which
report the state of the tablet battery.

Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
drivers/hid/wacom_wac.c
drivers/hid/wacom_wac.h
include/linux/hid.h

index 70de1fa930ccd6bd4b95af56d61826c3d8608f18..f3edecf52c0692dc66858e8bcdb9070b4f1e22b0 100644 (file)
@@ -1525,6 +1525,10 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev,
        unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);
 
        switch (equivalent_usage) {
+       case WACOM_HID_WD_BATTERY_LEVEL:
+       case WACOM_HID_WD_BATTERY_CHARGING:
+               features->quirks |= WACOM_QUIRK_BATTERY;
+               break;
        case WACOM_HID_WD_ACCELEROMETER_X:
                __set_bit(INPUT_PROP_ACCELEROMETER, input->propbit);
                wacom_map_usage(input, usage, field, EV_ABS, ABS_X, 0);
@@ -1574,8 +1578,25 @@ static int wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field,
                wacom_wac->hid_data.inrange_state |= value;
        }
 
-       if (equivalent_usage != WACOM_HID_WD_TOUCHRINGSTATUS)
+       switch (equivalent_usage) {
+       case WACOM_HID_WD_BATTERY_LEVEL:
+               wacom_wac->hid_data.battery_capacity = value;
+               wacom_wac->hid_data.bat_connected = 1;
+               return 0;
+
+       case WACOM_HID_WD_BATTERY_CHARGING:
+               wacom_wac->hid_data.bat_charging = value;
+               wacom_wac->hid_data.ps_connected = value;
+               wacom_wac->hid_data.bat_connected = 1;
+               return 0;
+
+       case WACOM_HID_WD_TOUCHRINGSTATUS:
+               return 0;
+
+       default:
                input_event(input, usage->type, usage->code, value);
+               break;
+       }
 
        return 0;
 }
@@ -1594,6 +1615,7 @@ static void wacom_wac_pad_report(struct hid_device *hdev,
 {
        struct wacom *wacom = hid_get_drvdata(hdev);
        struct wacom_wac *wacom_wac = &wacom->wacom_wac;
+       struct wacom_features *features = &wacom_wac->features;
        struct input_dev *input = wacom_wac->pad_input;
        bool active = wacom_wac->hid_data.inrange_state != 0;
 
@@ -1604,6 +1626,16 @@ static void wacom_wac_pad_report(struct hid_device *hdev,
        if (wacom_equivalent_usage(report->field[0]->physical) == HID_DG_TABLETFUNCTIONKEY)
                input_event(input, EV_ABS, ABS_MISC, active ? PAD_DEVICE_ID : 0);
 
+       if (features->quirks & WACOM_QUIRK_BATTERY) {
+               int capacity = wacom_wac->hid_data.battery_capacity;
+               bool charging = wacom_wac->hid_data.bat_charging;
+               bool connected = wacom_wac->hid_data.bat_connected;
+               bool powered = wacom_wac->hid_data.ps_connected;
+
+               wacom_notify_battery(wacom_wac, capacity, charging,
+                                    connected, powered);
+       }
+
        input_sync(input);
 }
 
@@ -1633,6 +1665,9 @@ static void wacom_wac_pen_usage_mapping(struct hid_device *hdev,
        case HID_DG_INRANGE:
                wacom_map_usage(input, usage, field, EV_KEY, BTN_TOOL_PEN, 0);
                break;
+       case HID_DG_BATTERYSTRENGTH:
+               features->quirks |= WACOM_QUIRK_BATTERY;
+               break;
        case HID_DG_INVERT:
                wacom_map_usage(input, usage, field, EV_KEY,
                                BTN_TOOL_RUBBER, 0);
@@ -1703,6 +1738,10 @@ static int wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field,
                if (!(features->quirks & WACOM_QUIRK_SENSE))
                        wacom_wac->hid_data.sense_state = value;
                return 0;
+       case HID_DG_BATTERYSTRENGTH:
+               wacom_wac->hid_data.battery_capacity = value;
+               wacom_wac->hid_data.bat_connected = 1;
+               break;
        case HID_DG_INVERT:
                wacom_wac->hid_data.invert_state = value;
                return 0;
index 1f7c4a86d91b2b043583e48d312fad439019b48b..7418c9715d3127dcff7eea77fa21f1cc1e8bc36a 100644 (file)
 #define WACOM_HID_WD_ACCELEROMETER_X    (WACOM_HID_UP_WACOMDIGITIZER | 0x0401)
 #define WACOM_HID_WD_ACCELEROMETER_Y    (WACOM_HID_UP_WACOMDIGITIZER | 0x0402)
 #define WACOM_HID_WD_ACCELEROMETER_Z    (WACOM_HID_UP_WACOMDIGITIZER | 0x0403)
+#define WACOM_HID_WD_BATTERY_CHARGING   (WACOM_HID_UP_WACOMDIGITIZER | 0x0404)
+#define WACOM_HID_WD_BATTERY_LEVEL      (WACOM_HID_UP_WACOMDIGITIZER | 0x043b)
 #define WACOM_HID_WD_EXPRESSKEY00       (WACOM_HID_UP_WACOMDIGITIZER | 0x0910)
 #define WACOM_HID_WD_BUTTONHOME         (WACOM_HID_UP_WACOMDIGITIZER | 0x0990)
 #define WACOM_HID_WD_BUTTONUP           (WACOM_HID_UP_WACOMDIGITIZER | 0x0991)
@@ -257,6 +259,10 @@ struct hid_data {
        int last_slot_field;
        int num_expected;
        int num_received;
+       int battery_capacity;
+       int bat_charging;
+       int bat_connected;
+       int ps_connected;
 };
 
 struct wacom_remote_data {
index e712101a167033916de3fb829afcc76e04c424ea..3baa2f962e481200fd1ff0e4de1818fe91eb7885 100644 (file)
@@ -231,6 +231,7 @@ struct hid_item {
 #define HID_DG_TAP             0x000d0035
 #define HID_DG_TABLETFUNCTIONKEY       0x000d0039
 #define HID_DG_PROGRAMCHANGEKEY        0x000d003a
+#define HID_DG_BATTERYSTRENGTH 0x000d003b
 #define HID_DG_INVERT          0x000d003c
 #define HID_DG_TILT_X          0x000d003d
 #define HID_DG_TILT_Y          0x000d003e