HID: wacom: Add battery presence indicator to wireless tablets
authorJason Gerecke <killertofu@gmail.com>
Wed, 11 Mar 2015 17:25:41 +0000 (10:25 -0700)
committerJiri Kosina <jkosina@suse.cz>
Wed, 11 Mar 2015 17:50:04 +0000 (13:50 -0400)
Declare the POWER_SUPPLY_PROP_PRESENT property to provide userspace
with a way to determine if the battery on a wireless tablet is plugged
in. Although current wireless tablets do not explicitly report this
information, it can be inferred from other state information. In
particular, a battery is assumed to be present if any of the following
are true: a non-zero battery level reported, the battery is reported as
charging, or the tablet is operating wirelessly.

Note: The last condition above may not strictly hold for the Graphire
Wireless (it charges from a DC barrel jack instead of a USB port), but I
do not know what is reported in the no-battery condition.

Signed-off-by: Jason Gerecke <killertofu@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
drivers/hid/wacom_sys.c
drivers/hid/wacom_wac.c
drivers/hid/wacom_wac.h

index 955ce7ceda898c03913ce001555bdb1d873d6d7d..ab7bf84c1ca746c6963b5da18568016e5a343766 100644 (file)
@@ -945,6 +945,7 @@ static void wacom_destroy_leds(struct wacom *wacom)
 }
 
 static enum power_supply_property wacom_battery_props[] = {
+       POWER_SUPPLY_PROP_PRESENT,
        POWER_SUPPLY_PROP_STATUS,
        POWER_SUPPLY_PROP_SCOPE,
        POWER_SUPPLY_PROP_CAPACITY
@@ -964,6 +965,9 @@ static int wacom_battery_get_property(struct power_supply *psy,
        int ret = 0;
 
        switch (psp) {
+               case POWER_SUPPLY_PROP_PRESENT:
+                       val->intval = wacom->wacom_wac.bat_connected;
+                       break;
                case POWER_SUPPLY_PROP_SCOPE:
                        val->intval = POWER_SUPPLY_SCOPE_DEVICE;
                        break;
index 57faf5b68b3d213acd03334f3637a544b772ab8a..92626228d7b5ed85b72339f0e63d428a3619a39b 100644 (file)
@@ -46,16 +46,19 @@ static unsigned short batcap_gr[8] = { 1, 15, 25, 35, 50, 70, 100, 100 };
 static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 };
 
 static void wacom_notify_battery(struct wacom_wac *wacom_wac,
-       int bat_capacity, bool bat_charging, bool ps_connected)
+       int bat_capacity, bool bat_charging, bool bat_connected,
+       bool ps_connected)
 {
        struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
        bool changed = wacom_wac->battery_capacity != bat_capacity  ||
                       wacom_wac->bat_charging     != bat_charging  ||
+                      wacom_wac->bat_connected    != bat_connected ||
                       wacom_wac->ps_connected     != ps_connected;
 
        if (changed) {
                wacom_wac->battery_capacity = bat_capacity;
                wacom_wac->bat_charging = bat_charging;
+               wacom_wac->bat_connected = bat_connected;
                wacom_wac->ps_connected = ps_connected;
 
                if (wacom->battery.dev)
@@ -438,7 +441,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom)
                battery_capacity = batcap_gr[rw];
                ps_connected = rw == 7;
                wacom_notify_battery(wacom, battery_capacity, ps_connected,
-                                    ps_connected);
+                                    1, ps_connected);
        }
 exit:
        return retval;
@@ -1029,6 +1032,7 @@ static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len)
                ps_connected = (power_raw & 0x10) ? 1 : 0;
                battery_capacity = batcap_i4[power_raw & 0x07];
                wacom_notify_battery(wacom, battery_capacity, bat_charging,
+                                    battery_capacity || bat_charging,
                                     ps_connected);
                break;
        default:
@@ -1936,13 +1940,13 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
                }
 
                if (wacom->shared->type)
-                       wacom_notify_battery(wacom, battery, charging, 0);
+                       wacom_notify_battery(wacom, battery, charging, 1, 0);
 
        } else if (wacom->pid != 0) {
                /* disconnected while previously connected */
                wacom->pid = 0;
                wacom_schedule_work(wacom);
-               wacom_notify_battery(wacom, 0, 0, 0);
+               wacom_notify_battery(wacom, 0, 0, 0, 0);
        }
 
        return 0;
@@ -1970,7 +1974,7 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len)
                bool charging = !!(data[8] & 0x80);
 
                wacom_notify_battery(wacom_wac, battery, charging,
-                                    1);
+                                    battery || charging, 1);
 
                if (!wacom->battery.dev &&
                    !(features->quirks & WACOM_QUIRK_BATTERY)) {
@@ -1984,7 +1988,7 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len)
                features->quirks &= ~WACOM_QUIRK_BATTERY;
                INIT_WORK(&wacom->work, wacom_battery_work);
                wacom_schedule_work(wacom_wac);
-               wacom_notify_battery(wacom_wac, 0, 0, 0);
+               wacom_notify_battery(wacom_wac, 0, 0, 0, 0);
        }
        return 0;
 }
index a3d0828ff8b13180de03b9b8f5e737642b54b57d..1c7d8931f1fa9ea190847adbaff68dd97b427073 100644 (file)
@@ -212,6 +212,7 @@ struct wacom_wac {
        int battery_capacity;
        int num_contacts_left;
        int bat_charging;
+       int bat_connected;
        int ps_connected;
        u8 bt_features;
        u8 bt_high_speed;