Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

HID: wacom: Add ability to provide explicit battery status info

At the moment, our driver relies on 'wacom_battery_get_property()' to
determine the most likely battery state (e.g charging, discharging, or
full) based on the information available. It is not always possible
for the function to properly determine this, however. For instance,
whenever an AES pen leaves proximity the battery state becomes
indeterminite. This commit adds the ability to provide it with explict
state information if desired. Whenever explicit state is not required
(the majority of circumstances), WACOM_POWER_SUPPLY_STATUS_AUTO can
be used in its place.

Three uses of explicit battery status are added: two wireless disconnect
paths and the AES case mentioned above.

Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
Reviewed-by: Ping Cheng <ping.cheng@wacom.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>

authored by

Jason Gerecke and committed by
Jiri Kosina
16e45989 a7758702

+45 -25
+1
drivers/hid/wacom.h
··· 138 138 struct power_supply_desc bat_desc; 139 139 struct power_supply *battery; 140 140 char bat_name[WACOM_NAME_MAX]; 141 + int bat_status; 141 142 int battery_capacity; 142 143 int bat_charging; 143 144 int bat_connected;
+3 -1
drivers/hid/wacom_sys.c
··· 1547 1547 val->intval = battery->battery_capacity; 1548 1548 break; 1549 1549 case POWER_SUPPLY_PROP_STATUS: 1550 - if (battery->bat_charging) 1550 + if (battery->bat_status != WACOM_POWER_SUPPLY_STATUS_AUTO) 1551 + val->intval = battery->bat_status; 1552 + else if (battery->bat_charging) 1551 1553 val->intval = POWER_SUPPLY_STATUS_CHARGING; 1552 1554 else if (battery->battery_capacity == 100 && 1553 1555 battery->ps_connected)
+38 -24
drivers/hid/wacom_wac.c
··· 57 57 static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 }; 58 58 59 59 static void __wacom_notify_battery(struct wacom_battery *battery, 60 - int bat_capacity, bool bat_charging, 61 - bool bat_connected, bool ps_connected) 60 + int bat_status, int bat_capacity, 61 + bool bat_charging, bool bat_connected, 62 + bool ps_connected) 62 63 { 63 - bool changed = battery->battery_capacity != bat_capacity || 64 + bool changed = battery->bat_status != bat_status || 65 + battery->battery_capacity != bat_capacity || 64 66 battery->bat_charging != bat_charging || 65 67 battery->bat_connected != bat_connected || 66 68 battery->ps_connected != ps_connected; 67 69 68 70 if (changed) { 71 + battery->bat_status = bat_status; 69 72 battery->battery_capacity = bat_capacity; 70 73 battery->bat_charging = bat_charging; 71 74 battery->bat_connected = bat_connected; ··· 80 77 } 81 78 82 79 static void wacom_notify_battery(struct wacom_wac *wacom_wac, 83 - int bat_capacity, bool bat_charging, bool bat_connected, 84 - bool ps_connected) 80 + int bat_status, int bat_capacity, bool bat_charging, 81 + bool bat_connected, bool ps_connected) 85 82 { 86 83 struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); 87 84 88 - __wacom_notify_battery(&wacom->battery, bat_capacity, bat_charging, 89 - bat_connected, ps_connected); 85 + __wacom_notify_battery(&wacom->battery, bat_status, bat_capacity, 86 + bat_charging, bat_connected, ps_connected); 90 87 } 91 88 92 89 static int wacom_penpartner_irq(struct wacom_wac *wacom) ··· 451 448 rw = (data[7] >> 2 & 0x07); 452 449 battery_capacity = batcap_gr[rw]; 453 450 ps_connected = rw == 7; 454 - wacom_notify_battery(wacom, battery_capacity, ps_connected, 455 - 1, ps_connected); 451 + wacom_notify_battery(wacom, WACOM_POWER_SUPPLY_STATUS_AUTO, 452 + battery_capacity, ps_connected, 1, 453 + ps_connected); 456 454 } 457 455 exit: 458 456 return retval; ··· 1075 1071 wacom->led.groups[i].select = touch_ring_mode; 1076 1072 } 1077 1073 1078 - __wacom_notify_battery(&remote->remotes[index].battery, bat_percent, 1074 + __wacom_notify_battery(&remote->remotes[index].battery, 1075 + WACOM_POWER_SUPPLY_STATUS_AUTO, bat_percent, 1079 1076 bat_charging, 1, bat_charging); 1080 1077 1081 1078 out: ··· 1162 1157 bat_charging = (power_raw & 0x08) ? 1 : 0; 1163 1158 ps_connected = (power_raw & 0x10) ? 1 : 0; 1164 1159 battery_capacity = batcap_i4[power_raw & 0x07]; 1165 - wacom_notify_battery(wacom, battery_capacity, bat_charging, 1160 + wacom_notify_battery(wacom, WACOM_POWER_SUPPLY_STATUS_AUTO, 1161 + battery_capacity, bat_charging, 1166 1162 battery_capacity || bat_charging, 1167 1163 ps_connected); 1168 1164 break; ··· 1340 1334 bool chg = data[284] & 0x80; 1341 1335 int battery_status = data[284] & 0x7F; 1342 1336 1343 - wacom_notify_battery(wacom, battery_status, chg, 1, chg); 1337 + wacom_notify_battery(wacom, WACOM_POWER_SUPPLY_STATUS_AUTO, 1338 + battery_status, chg, 1, chg); 1344 1339 } 1345 1340 1346 1341 static int wacom_intuos_pro2_bt_irq(struct wacom_wac *wacom, size_t len) ··· 1821 1814 value = value * 100 / (field->logical_maximum - field->logical_minimum); 1822 1815 wacom_wac->hid_data.battery_capacity = value; 1823 1816 wacom_wac->hid_data.bat_connected = 1; 1817 + wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO; 1824 1818 break; 1825 1819 1826 1820 case WACOM_HID_WD_BATTERY_CHARGING: ··· 1913 1905 struct wacom_features *features = &wacom_wac->features; 1914 1906 1915 1907 if (features->quirks & WACOM_QUIRK_BATTERY) { 1908 + int status = wacom_wac->hid_data.bat_status; 1916 1909 int capacity = wacom_wac->hid_data.battery_capacity; 1917 1910 bool charging = wacom_wac->hid_data.bat_charging; 1918 1911 bool connected = wacom_wac->hid_data.bat_connected; 1919 1912 bool powered = wacom_wac->hid_data.ps_connected; 1920 1913 1921 - wacom_notify_battery(wacom_wac, capacity, charging, 1922 - connected, powered); 1914 + wacom_notify_battery(wacom_wac, status, capacity, 1915 + charging, connected, powered); 1923 1916 } 1924 1917 } 1925 1918 ··· 2045 2036 wacom_wac->hid_data.sense_state = value; 2046 2037 return; 2047 2038 case HID_DG_BATTERYSTRENGTH: 2048 - if (value == 0) /* "not available" */ 2049 - break; 2050 - value = value * 100 / (field->logical_maximum - field->logical_minimum); 2051 - wacom_wac->hid_data.battery_capacity = value; 2052 - wacom_wac->hid_data.bat_connected = 1; 2039 + if (value == 0) { 2040 + wacom_wac->hid_data.bat_status = POWER_SUPPLY_STATUS_UNKNOWN; 2041 + } 2042 + else { 2043 + value = value * 100 / (field->logical_maximum - field->logical_minimum); 2044 + wacom_wac->hid_data.battery_capacity = value; 2045 + wacom_wac->hid_data.bat_connected = 1; 2046 + wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO; 2047 + } 2053 2048 break; 2054 2049 case HID_DG_INVERT: 2055 2050 wacom_wac->hid_data.invert_state = value; ··· 2831 2818 wacom_schedule_work(wacom, WACOM_WORKER_WIRELESS); 2832 2819 } 2833 2820 2834 - wacom_notify_battery(wacom, battery, charging, 1, 0); 2821 + wacom_notify_battery(wacom, WACOM_POWER_SUPPLY_STATUS_AUTO, 2822 + battery, charging, 1, 0); 2835 2823 2836 2824 } else if (wacom->pid != 0) { 2837 2825 /* disconnected while previously connected */ 2838 2826 wacom->pid = 0; 2839 2827 wacom_schedule_work(wacom, WACOM_WORKER_WIRELESS); 2840 - wacom_notify_battery(wacom, 0, 0, 0, 0); 2828 + wacom_notify_battery(wacom, POWER_SUPPLY_STATUS_UNKNOWN, 0, 0, 0, 0); 2841 2829 } 2842 2830 2843 2831 return 0; ··· 2866 2852 int battery = (data[8] & 0x3f) * 100 / 31; 2867 2853 bool charging = !!(data[8] & 0x80); 2868 2854 2869 - wacom_notify_battery(wacom_wac, battery, charging, 2870 - battery || charging, 1); 2855 + wacom_notify_battery(wacom_wac, WACOM_POWER_SUPPLY_STATUS_AUTO, 2856 + battery, charging, battery || charging, 1); 2871 2857 2872 2858 if (!wacom->battery.battery && 2873 2859 !(features->quirks & WACOM_QUIRK_BATTERY)) { ··· 2879 2865 wacom->battery.battery) { 2880 2866 features->quirks &= ~WACOM_QUIRK_BATTERY; 2881 2867 wacom_schedule_work(wacom_wac, WACOM_WORKER_BATTERY); 2882 - wacom_notify_battery(wacom_wac, 0, 0, 0, 0); 2868 + wacom_notify_battery(wacom_wac, POWER_SUPPLY_STATUS_UNKNOWN, 0, 0, 0, 0); 2883 2869 } 2884 2870 return 0; 2885 2871 }
+3
drivers/hid/wacom_wac.h
··· 96 96 #define WACOM_DEVICETYPE_WL_MONITOR 0x0008 97 97 #define WACOM_DEVICETYPE_DIRECT 0x0010 98 98 99 + #define WACOM_POWER_SUPPLY_STATUS_AUTO -1 100 + 99 101 #define WACOM_HID_UP_WACOMDIGITIZER 0xff0d0000 100 102 #define WACOM_HID_SP_PAD 0x00040000 101 103 #define WACOM_HID_SP_BUTTON 0x00090000 ··· 299 297 int last_slot_field; 300 298 int num_expected; 301 299 int num_received; 300 + int bat_status; 302 301 int battery_capacity; 303 302 int bat_charging; 304 303 int bat_connected;