Commit ac8d1010 authored by Benjamin Tissoires's avatar Benjamin Tissoires Committed by Dmitry Torokhov

Input: wacom - enhance Wireless Receiver battery reporting

- Reports the current status of the battery (discharging, charging, full).
- Also notify the upower daemon when there is a change in the battery
  value.
- keep the battery value as a percentage, not the raw value
- add WACOM_QUIRK_BATTERY to easily add a battery to a device (required
  for Bluetooth devices)
Signed-off-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Acked-by: default avatarPrzemo Firszt <przemo@firszt.eu>
Acked-by: default avatarPing Cheng <pingc@wacom.com>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent c757cbaf
......@@ -128,6 +128,13 @@ static inline void wacom_schedule_work(struct wacom_wac *wacom_wac)
schedule_work(&wacom->work);
}
static inline void wacom_notify_battery(struct wacom_wac *wacom_wac)
{
struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
power_supply_changed(&wacom->battery);
}
extern const struct hid_device_id wacom_ids[];
void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len);
......
......@@ -769,6 +769,7 @@ static void wacom_destroy_leds(struct wacom *wacom)
}
static enum power_supply_property wacom_battery_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_SCOPE,
POWER_SUPPLY_PROP_CAPACITY
};
......@@ -786,7 +787,16 @@ static int wacom_battery_get_property(struct power_supply *psy,
break;
case POWER_SUPPLY_PROP_CAPACITY:
val->intval =
wacom->wacom_wac.battery_capacity * 100 / 31;
wacom->wacom_wac.battery_capacity;
break;
case POWER_SUPPLY_PROP_STATUS:
if (wacom->wacom_wac.bat_charging)
val->intval = POWER_SUPPLY_STATUS_CHARGING;
else if (wacom->wacom_wac.battery_capacity == 100 &&
wacom->wacom_wac.ps_connected)
val->intval = POWER_SUPPLY_STATUS_FULL;
else
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
break;
default:
ret = -EINVAL;
......@@ -800,7 +810,7 @@ static int wacom_initialize_battery(struct wacom *wacom)
{
int error = 0;
if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_MONITOR) {
if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) {
wacom->battery.properties = wacom_battery_props;
wacom->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
wacom->battery.get_property = wacom_battery_get_property;
......@@ -821,8 +831,8 @@ static int wacom_initialize_battery(struct wacom *wacom)
static void wacom_destroy_battery(struct wacom *wacom)
{
if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_MONITOR &&
wacom->battery.dev) {
if ((wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) &&
wacom->battery.dev) {
power_supply_unregister(&wacom->battery);
wacom->battery.dev = NULL;
}
......@@ -947,6 +957,7 @@ static void wacom_wireless_work(struct work_struct *work)
if (wacom_wac->pid == 0) {
hid_info(wacom->hdev, "wireless tablet disconnected\n");
wacom_wac1->shared->type = 0;
} else {
const struct hid_device_id *id = wacom_ids;
......
......@@ -1365,7 +1365,7 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
connected = data[1] & 0x01;
if (connected) {
int pid, battery;
int pid, battery, ps_connected;
if ((wacom->shared->type == INTUOSHT) &&
wacom->shared->touch_max) {
......@@ -1375,17 +1375,29 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
}
pid = get_unaligned_be16(&data[6]);
battery = data[5] & 0x3f;
battery = (data[5] & 0x3f) * 100 / 31;
ps_connected = !!(data[5] & 0x80);
if (wacom->pid != pid) {
wacom->pid = pid;
wacom_schedule_work(wacom);
}
wacom->battery_capacity = battery;
if (wacom->shared->type &&
(battery != wacom->battery_capacity ||
ps_connected != wacom->ps_connected)) {
wacom->battery_capacity = battery;
wacom->ps_connected = ps_connected;
wacom->bat_charging = ps_connected &&
wacom->battery_capacity < 100;
wacom_notify_battery(wacom);
}
} else if (wacom->pid != 0) {
/* disconnected while previously connected */
wacom->pid = 0;
wacom_schedule_work(wacom);
wacom->battery_capacity = 0;
wacom->bat_charging = 0;
wacom->ps_connected = 0;
}
return 0;
......@@ -1558,8 +1570,10 @@ void wacom_setup_device_quirks(struct wacom_features *features)
features->quirks |= WACOM_QUIRK_NO_INPUT;
/* must be monitor interface if no device_type set */
if (!features->device_type)
if (!features->device_type) {
features->quirks |= WACOM_QUIRK_MONITOR;
features->quirks |= WACOM_QUIRK_BATTERY;
}
}
}
......
......@@ -68,6 +68,7 @@
#define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002
#define WACOM_QUIRK_NO_INPUT 0x0004
#define WACOM_QUIRK_MONITOR 0x0008
#define WACOM_QUIRK_BATTERY 0x0010
enum {
PENPARTNER = 0,
......@@ -164,6 +165,8 @@ struct wacom_wac {
int pid;
int battery_capacity;
int num_contacts_left;
int bat_charging;
int ps_connected;
};
#endif
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