HID: input: map battery system charging
[linux-2.6-microblaze.git] / drivers / hid / hid-input.c
index 3a93cf0..796930a 100644 (file)
@@ -480,7 +480,7 @@ static int hidinput_get_battery_property(struct power_supply *psy,
                if (dev->battery_status == HID_BATTERY_UNKNOWN)
                        val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
                else
-                       val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+                       val->intval = dev->battery_charge_status;
                break;
 
        case POWER_SUPPLY_PROP_SCOPE:
@@ -548,6 +548,7 @@ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
        dev->battery_max = max;
        dev->battery_report_type = report_type;
        dev->battery_report_id = field->report->id;
+       dev->battery_charge_status = POWER_SUPPLY_STATUS_DISCHARGING;
 
        /*
         * Stylus is normally not connected to the device and thus we
@@ -614,6 +615,20 @@ static void hidinput_update_battery(struct hid_device *dev, int value)
                power_supply_changed(dev->battery);
        }
 }
+
+static bool hidinput_set_battery_charge_status(struct hid_device *dev,
+                                              unsigned int usage, int value)
+{
+       switch (usage) {
+       case HID_BAT_CHARGING:
+               dev->battery_charge_status = value ?
+                                            POWER_SUPPLY_STATUS_CHARGING :
+                                            POWER_SUPPLY_STATUS_DISCHARGING;
+               return true;
+       }
+
+       return false;
+}
 #else  /* !CONFIG_HID_BATTERY_STRENGTH */
 static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
                                  struct hid_field *field, bool is_percentage)
@@ -628,6 +643,12 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
 static void hidinput_update_battery(struct hid_device *dev, int value)
 {
 }
+
+static bool hidinput_set_battery_charge_status(struct hid_device *dev,
+                                              unsigned int usage, int value)
+{
+       return false;
+}
 #endif /* CONFIG_HID_BATTERY_STRENGTH */
 
 static bool hidinput_field_in_collection(struct hid_device *device, struct hid_field *field,
@@ -1217,6 +1238,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                        hidinput_setup_battery(device, HID_INPUT_REPORT, field, true);
                        usage->type = EV_PWR;
                        return;
+               case HID_BAT_CHARGING:
+                       usage->type = EV_PWR;
+                       return;
                }
                goto unknown;
 
@@ -1459,7 +1483,11 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
                return;
 
        if (usage->type == EV_PWR) {
-               hidinput_update_battery(hid, value);
+               bool handled = hidinput_set_battery_charge_status(hid, usage->hid, value);
+
+               if (!handled)
+                       hidinput_update_battery(hid, value);
+
                return;
        }
 
@@ -2315,3 +2343,7 @@ void hidinput_disconnect(struct hid_device *hid)
        cancel_work_sync(&hid->led_work);
 }
 EXPORT_SYMBOL_GPL(hidinput_disconnect);
+
+#ifdef CONFIG_HID_KUNIT_TEST
+#include "hid-input-test.c"
+#endif