Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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);
+15 −4
Original line number Diff line number Diff line
@@ -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,7 +831,7 @@ 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 &&
	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;

+18 −4
Original line number Diff line number Diff line
@@ -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);
		}

		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;
		}
	}
}

+3 −0
Original line number Diff line number Diff line
@@ -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