aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2014-07-25 20:29:48 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-07-25 21:55:53 -0400
commitac8d10101b0e3a0a1478f8bb51bbbb0a56fe0956 (patch)
treeb0c3b337484358d079bcf13e9d9e754cc71bd5bd
parentc757cbafd6afe8e47d12320aa05edcd1b1d97186 (diff)
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: Benjamin Tissoires <benjamin.tissoires@redhat.com> Acked-by: Przemo Firszt <przemo@firszt.eu> Acked-by: Ping Cheng <pingc@wacom.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--drivers/hid/wacom.h7
-rw-r--r--drivers/hid/wacom_sys.c19
-rw-r--r--drivers/hid/wacom_wac.c22
-rw-r--r--drivers/hid/wacom_wac.h3
4 files changed, 43 insertions, 8 deletions
diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h
index a678f827e39e..98cb93f16ba4 100644
--- a/drivers/hid/wacom.h
+++ b/drivers/hid/wacom.h
@@ -128,6 +128,13 @@ static inline void wacom_schedule_work(struct wacom_wac *wacom_wac)
128 schedule_work(&wacom->work); 128 schedule_work(&wacom->work);
129} 129}
130 130
131static inline void wacom_notify_battery(struct wacom_wac *wacom_wac)
132{
133 struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
134
135 power_supply_changed(&wacom->battery);
136}
137
131extern const struct hid_device_id wacom_ids[]; 138extern const struct hid_device_id wacom_ids[];
132 139
133void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); 140void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len);
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index f1c6d3dae248..f8744c4d3b18 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -769,6 +769,7 @@ static void wacom_destroy_leds(struct wacom *wacom)
769} 769}
770 770
771static enum power_supply_property wacom_battery_props[] = { 771static enum power_supply_property wacom_battery_props[] = {
772 POWER_SUPPLY_PROP_STATUS,
772 POWER_SUPPLY_PROP_SCOPE, 773 POWER_SUPPLY_PROP_SCOPE,
773 POWER_SUPPLY_PROP_CAPACITY 774 POWER_SUPPLY_PROP_CAPACITY
774}; 775};
@@ -786,7 +787,16 @@ static int wacom_battery_get_property(struct power_supply *psy,
786 break; 787 break;
787 case POWER_SUPPLY_PROP_CAPACITY: 788 case POWER_SUPPLY_PROP_CAPACITY:
788 val->intval = 789 val->intval =
789 wacom->wacom_wac.battery_capacity * 100 / 31; 790 wacom->wacom_wac.battery_capacity;
791 break;
792 case POWER_SUPPLY_PROP_STATUS:
793 if (wacom->wacom_wac.bat_charging)
794 val->intval = POWER_SUPPLY_STATUS_CHARGING;
795 else if (wacom->wacom_wac.battery_capacity == 100 &&
796 wacom->wacom_wac.ps_connected)
797 val->intval = POWER_SUPPLY_STATUS_FULL;
798 else
799 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
790 break; 800 break;
791 default: 801 default:
792 ret = -EINVAL; 802 ret = -EINVAL;
@@ -800,7 +810,7 @@ static int wacom_initialize_battery(struct wacom *wacom)
800{ 810{
801 int error = 0; 811 int error = 0;
802 812
803 if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_MONITOR) { 813 if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) {
804 wacom->battery.properties = wacom_battery_props; 814 wacom->battery.properties = wacom_battery_props;
805 wacom->battery.num_properties = ARRAY_SIZE(wacom_battery_props); 815 wacom->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
806 wacom->battery.get_property = wacom_battery_get_property; 816 wacom->battery.get_property = wacom_battery_get_property;
@@ -821,8 +831,8 @@ static int wacom_initialize_battery(struct wacom *wacom)
821 831
822static void wacom_destroy_battery(struct wacom *wacom) 832static void wacom_destroy_battery(struct wacom *wacom)
823{ 833{
824 if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_MONITOR && 834 if ((wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) &&
825 wacom->battery.dev) { 835 wacom->battery.dev) {
826 power_supply_unregister(&wacom->battery); 836 power_supply_unregister(&wacom->battery);
827 wacom->battery.dev = NULL; 837 wacom->battery.dev = NULL;
828 } 838 }
@@ -947,6 +957,7 @@ static void wacom_wireless_work(struct work_struct *work)
947 957
948 if (wacom_wac->pid == 0) { 958 if (wacom_wac->pid == 0) {
949 hid_info(wacom->hdev, "wireless tablet disconnected\n"); 959 hid_info(wacom->hdev, "wireless tablet disconnected\n");
960 wacom_wac1->shared->type = 0;
950 } else { 961 } else {
951 const struct hid_device_id *id = wacom_ids; 962 const struct hid_device_id *id = wacom_ids;
952 963
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 2f3a3a77d0c6..cfd2ae13c287 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1365,7 +1365,7 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
1365 1365
1366 connected = data[1] & 0x01; 1366 connected = data[1] & 0x01;
1367 if (connected) { 1367 if (connected) {
1368 int pid, battery; 1368 int pid, battery, ps_connected;
1369 1369
1370 if ((wacom->shared->type == INTUOSHT) && 1370 if ((wacom->shared->type == INTUOSHT) &&
1371 wacom->shared->touch_max) { 1371 wacom->shared->touch_max) {
@@ -1375,17 +1375,29 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
1375 } 1375 }
1376 1376
1377 pid = get_unaligned_be16(&data[6]); 1377 pid = get_unaligned_be16(&data[6]);
1378 battery = data[5] & 0x3f; 1378 battery = (data[5] & 0x3f) * 100 / 31;
1379 ps_connected = !!(data[5] & 0x80);
1379 if (wacom->pid != pid) { 1380 if (wacom->pid != pid) {
1380 wacom->pid = pid; 1381 wacom->pid = pid;
1381 wacom_schedule_work(wacom); 1382 wacom_schedule_work(wacom);
1382 } 1383 }
1383 wacom->battery_capacity = battery; 1384
1385 if (wacom->shared->type &&
1386 (battery != wacom->battery_capacity ||
1387 ps_connected != wacom->ps_connected)) {
1388 wacom->battery_capacity = battery;
1389 wacom->ps_connected = ps_connected;
1390 wacom->bat_charging = ps_connected &&
1391 wacom->battery_capacity < 100;
1392 wacom_notify_battery(wacom);
1393 }
1384 } else if (wacom->pid != 0) { 1394 } else if (wacom->pid != 0) {
1385 /* disconnected while previously connected */ 1395 /* disconnected while previously connected */
1386 wacom->pid = 0; 1396 wacom->pid = 0;
1387 wacom_schedule_work(wacom); 1397 wacom_schedule_work(wacom);
1388 wacom->battery_capacity = 0; 1398 wacom->battery_capacity = 0;
1399 wacom->bat_charging = 0;
1400 wacom->ps_connected = 0;
1389 } 1401 }
1390 1402
1391 return 0; 1403 return 0;
@@ -1558,8 +1570,10 @@ void wacom_setup_device_quirks(struct wacom_features *features)
1558 features->quirks |= WACOM_QUIRK_NO_INPUT; 1570 features->quirks |= WACOM_QUIRK_NO_INPUT;
1559 1571
1560 /* must be monitor interface if no device_type set */ 1572 /* must be monitor interface if no device_type set */
1561 if (!features->device_type) 1573 if (!features->device_type) {
1562 features->quirks |= WACOM_QUIRK_MONITOR; 1574 features->quirks |= WACOM_QUIRK_MONITOR;
1575 features->quirks |= WACOM_QUIRK_BATTERY;
1576 }
1563 } 1577 }
1564} 1578}
1565 1579
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
index 4c592475b237..8a042ac0114e 100644
--- a/drivers/hid/wacom_wac.h
+++ b/drivers/hid/wacom_wac.h
@@ -68,6 +68,7 @@
68#define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002 68#define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002
69#define WACOM_QUIRK_NO_INPUT 0x0004 69#define WACOM_QUIRK_NO_INPUT 0x0004
70#define WACOM_QUIRK_MONITOR 0x0008 70#define WACOM_QUIRK_MONITOR 0x0008
71#define WACOM_QUIRK_BATTERY 0x0010
71 72
72enum { 73enum {
73 PENPARTNER = 0, 74 PENPARTNER = 0,
@@ -164,6 +165,8 @@ struct wacom_wac {
164 int pid; 165 int pid;
165 int battery_capacity; 166 int battery_capacity;
166 int num_contacts_left; 167 int num_contacts_left;
168 int bat_charging;
169 int ps_connected;
167}; 170};
168 171
169#endif 172#endif