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) ...@@ -128,6 +128,13 @@ static inline void wacom_schedule_work(struct wacom_wac *wacom_wac)
schedule_work(&wacom->work); 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[]; extern const struct hid_device_id wacom_ids[];
void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len);
......
...@@ -769,6 +769,7 @@ static void wacom_destroy_leds(struct wacom *wacom) ...@@ -769,6 +769,7 @@ static void wacom_destroy_leds(struct wacom *wacom)
} }
static enum power_supply_property wacom_battery_props[] = { static enum power_supply_property wacom_battery_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_SCOPE, POWER_SUPPLY_PROP_SCOPE,
POWER_SUPPLY_PROP_CAPACITY POWER_SUPPLY_PROP_CAPACITY
}; };
...@@ -786,7 +787,16 @@ static int wacom_battery_get_property(struct power_supply *psy, ...@@ -786,7 +787,16 @@ static int wacom_battery_get_property(struct power_supply *psy,
break; break;
case POWER_SUPPLY_PROP_CAPACITY: case POWER_SUPPLY_PROP_CAPACITY:
val->intval = 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; break;
default: default:
ret = -EINVAL; ret = -EINVAL;
...@@ -800,7 +810,7 @@ static int wacom_initialize_battery(struct wacom *wacom) ...@@ -800,7 +810,7 @@ static int wacom_initialize_battery(struct wacom *wacom)
{ {
int error = 0; 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.properties = wacom_battery_props;
wacom->battery.num_properties = ARRAY_SIZE(wacom_battery_props); wacom->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
wacom->battery.get_property = wacom_battery_get_property; wacom->battery.get_property = wacom_battery_get_property;
...@@ -821,8 +831,8 @@ static int wacom_initialize_battery(struct wacom *wacom) ...@@ -821,8 +831,8 @@ static int wacom_initialize_battery(struct wacom *wacom)
static void wacom_destroy_battery(struct wacom *wacom) static void wacom_destroy_battery(struct wacom *wacom)
{ {
if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_MONITOR && if ((wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) &&
wacom->battery.dev) { wacom->battery.dev) {
power_supply_unregister(&wacom->battery); power_supply_unregister(&wacom->battery);
wacom->battery.dev = NULL; wacom->battery.dev = NULL;
} }
...@@ -947,6 +957,7 @@ static void wacom_wireless_work(struct work_struct *work) ...@@ -947,6 +957,7 @@ static void wacom_wireless_work(struct work_struct *work)
if (wacom_wac->pid == 0) { if (wacom_wac->pid == 0) {
hid_info(wacom->hdev, "wireless tablet disconnected\n"); hid_info(wacom->hdev, "wireless tablet disconnected\n");
wacom_wac1->shared->type = 0;
} else { } else {
const struct hid_device_id *id = wacom_ids; const struct hid_device_id *id = wacom_ids;
......
...@@ -1365,7 +1365,7 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) ...@@ -1365,7 +1365,7 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
connected = data[1] & 0x01; connected = data[1] & 0x01;
if (connected) { if (connected) {
int pid, battery; int pid, battery, ps_connected;
if ((wacom->shared->type == INTUOSHT) && if ((wacom->shared->type == INTUOSHT) &&
wacom->shared->touch_max) { wacom->shared->touch_max) {
...@@ -1375,17 +1375,29 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) ...@@ -1375,17 +1375,29 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
} }
pid = get_unaligned_be16(&data[6]); 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) { if (wacom->pid != pid) {
wacom->pid = pid; wacom->pid = pid;
wacom_schedule_work(wacom); 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) { } else if (wacom->pid != 0) {
/* disconnected while previously connected */ /* disconnected while previously connected */
wacom->pid = 0; wacom->pid = 0;
wacom_schedule_work(wacom); wacom_schedule_work(wacom);
wacom->battery_capacity = 0; wacom->battery_capacity = 0;
wacom->bat_charging = 0;
wacom->ps_connected = 0;
} }
return 0; return 0;
...@@ -1558,8 +1570,10 @@ void wacom_setup_device_quirks(struct wacom_features *features) ...@@ -1558,8 +1570,10 @@ void wacom_setup_device_quirks(struct wacom_features *features)
features->quirks |= WACOM_QUIRK_NO_INPUT; features->quirks |= WACOM_QUIRK_NO_INPUT;
/* must be monitor interface if no device_type set */ /* 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_MONITOR;
features->quirks |= WACOM_QUIRK_BATTERY;
}
} }
} }
......
...@@ -68,6 +68,7 @@ ...@@ -68,6 +68,7 @@
#define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002 #define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002
#define WACOM_QUIRK_NO_INPUT 0x0004 #define WACOM_QUIRK_NO_INPUT 0x0004
#define WACOM_QUIRK_MONITOR 0x0008 #define WACOM_QUIRK_MONITOR 0x0008
#define WACOM_QUIRK_BATTERY 0x0010
enum { enum {
PENPARTNER = 0, PENPARTNER = 0,
...@@ -164,6 +165,8 @@ struct wacom_wac { ...@@ -164,6 +165,8 @@ struct wacom_wac {
int pid; int pid;
int battery_capacity; int battery_capacity;
int num_contacts_left; int num_contacts_left;
int bat_charging;
int ps_connected;
}; };
#endif #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