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

HID: wacom: generic: Refactor generic battery handling

Generic battery handling code is spread between the pen and pad codepaths
since battery usages may appear in reports for either. This makes it
difficult to concisely see the logic involved. Since battery data is
not treated like other data (i.e., we report it through the power_supply
subsystem rather than through the input subsystem), it makes reasonable
sense to split the functionality out into its own functions.

This commit has the generic battery handling duplicate the same pattern
that is used by the pen, pad, and touch interfaces. A "mapping" function
is provided to set up the battery, an "event" function is provided to
update the battery data, and a "report" function is provided to notify
the power_supply subsystem after all the data has been read. We look at
the usage itself rather than its collection to determine if one of the
battery functions should handle it. Additionally, we unconditionally
call the "report" function since there is no particularly good way to
know if a report contained a battery usage; 'wacom_notify_battery()'
will filter out any duplicate updates, however.

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
5ac3d4ae 16e45989

+97 -73
+93 -73
drivers/hid/wacom_wac.c
··· 1702 1702 } 1703 1703 } 1704 1704 1705 + static void wacom_wac_battery_usage_mapping(struct hid_device *hdev, 1706 + struct hid_field *field, struct hid_usage *usage) 1707 + { 1708 + struct wacom *wacom = hid_get_drvdata(hdev); 1709 + struct wacom_wac *wacom_wac = &wacom->wacom_wac; 1710 + struct wacom_features *features = &wacom_wac->features; 1711 + unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); 1712 + 1713 + switch (equivalent_usage) { 1714 + case HID_DG_BATTERYSTRENGTH: 1715 + case WACOM_HID_WD_BATTERY_LEVEL: 1716 + case WACOM_HID_WD_BATTERY_CHARGING: 1717 + features->quirks |= WACOM_QUIRK_BATTERY; 1718 + break; 1719 + } 1720 + } 1721 + 1722 + static void wacom_wac_battery_event(struct hid_device *hdev, struct hid_field *field, 1723 + struct hid_usage *usage, __s32 value) 1724 + { 1725 + struct wacom *wacom = hid_get_drvdata(hdev); 1726 + struct wacom_wac *wacom_wac = &wacom->wacom_wac; 1727 + unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); 1728 + 1729 + switch (equivalent_usage) { 1730 + case HID_DG_BATTERYSTRENGTH: 1731 + if (value == 0) { 1732 + wacom_wac->hid_data.bat_status = POWER_SUPPLY_STATUS_UNKNOWN; 1733 + } 1734 + else { 1735 + value = value * 100 / (field->logical_maximum - field->logical_minimum); 1736 + wacom_wac->hid_data.battery_capacity = value; 1737 + wacom_wac->hid_data.bat_connected = 1; 1738 + wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO; 1739 + } 1740 + break; 1741 + case WACOM_HID_WD_BATTERY_LEVEL: 1742 + value = value * 100 / (field->logical_maximum - field->logical_minimum); 1743 + wacom_wac->hid_data.battery_capacity = value; 1744 + wacom_wac->hid_data.bat_connected = 1; 1745 + wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO; 1746 + break; 1747 + case WACOM_HID_WD_BATTERY_CHARGING: 1748 + wacom_wac->hid_data.bat_charging = value; 1749 + wacom_wac->hid_data.ps_connected = value; 1750 + wacom_wac->hid_data.bat_connected = 1; 1751 + wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO; 1752 + break; 1753 + } 1754 + } 1755 + 1756 + static void wacom_wac_battery_pre_report(struct hid_device *hdev, 1757 + struct hid_report *report) 1758 + { 1759 + return; 1760 + } 1761 + 1762 + static void wacom_wac_battery_report(struct hid_device *hdev, 1763 + struct hid_report *report) 1764 + { 1765 + struct wacom *wacom = hid_get_drvdata(hdev); 1766 + struct wacom_wac *wacom_wac = &wacom->wacom_wac; 1767 + struct wacom_features *features = &wacom_wac->features; 1768 + 1769 + if (features->quirks & WACOM_QUIRK_BATTERY) { 1770 + int status = wacom_wac->hid_data.bat_status; 1771 + int capacity = wacom_wac->hid_data.battery_capacity; 1772 + bool charging = wacom_wac->hid_data.bat_charging; 1773 + bool connected = wacom_wac->hid_data.bat_connected; 1774 + bool powered = wacom_wac->hid_data.ps_connected; 1775 + 1776 + wacom_notify_battery(wacom_wac, status, capacity, charging, 1777 + connected, powered); 1778 + } 1779 + } 1780 + 1705 1781 static void wacom_wac_pad_usage_mapping(struct hid_device *hdev, 1706 1782 struct hid_field *field, struct hid_usage *usage) 1707 1783 { ··· 1788 1712 unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); 1789 1713 1790 1714 switch (equivalent_usage) { 1791 - case WACOM_HID_WD_BATTERY_LEVEL: 1792 - case WACOM_HID_WD_BATTERY_CHARGING: 1793 - features->quirks |= WACOM_QUIRK_BATTERY; 1794 - break; 1795 1715 case WACOM_HID_WD_ACCELEROMETER_X: 1796 1716 __set_bit(INPUT_PROP_ACCELEROMETER, input->propbit); 1797 1717 wacom_map_usage(input, usage, field, EV_ABS, ABS_X, 0); ··· 1881 1809 } 1882 1810 } 1883 1811 1884 - static void wacom_wac_pad_battery_event(struct hid_device *hdev, struct hid_field *field, 1885 - struct hid_usage *usage, __s32 value) 1886 - { 1887 - struct wacom *wacom = hid_get_drvdata(hdev); 1888 - struct wacom_wac *wacom_wac = &wacom->wacom_wac; 1889 - unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); 1890 - 1891 - switch (equivalent_usage) { 1892 - case WACOM_HID_WD_BATTERY_LEVEL: 1893 - value = value * 100 / (field->logical_maximum - field->logical_minimum); 1894 - wacom_wac->hid_data.battery_capacity = value; 1895 - wacom_wac->hid_data.bat_connected = 1; 1896 - wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO; 1897 - break; 1898 - 1899 - case WACOM_HID_WD_BATTERY_CHARGING: 1900 - wacom_wac->hid_data.bat_charging = value; 1901 - wacom_wac->hid_data.ps_connected = value; 1902 - wacom_wac->hid_data.bat_connected = 1; 1903 - break; 1904 - } 1905 - } 1906 - 1907 1812 static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field, 1908 1813 struct hid_usage *usage, __s32 value) 1909 1814 { ··· 1954 1905 wacom_wac->hid_data.inrange_state = 0; 1955 1906 } 1956 1907 1957 - static void wacom_wac_pad_battery_report(struct hid_device *hdev, 1958 - struct hid_report *report) 1959 - { 1960 - struct wacom *wacom = hid_get_drvdata(hdev); 1961 - struct wacom_wac *wacom_wac = &wacom->wacom_wac; 1962 - struct wacom_features *features = &wacom_wac->features; 1963 - 1964 - if (features->quirks & WACOM_QUIRK_BATTERY) { 1965 - int status = wacom_wac->hid_data.bat_status; 1966 - int capacity = wacom_wac->hid_data.battery_capacity; 1967 - bool charging = wacom_wac->hid_data.bat_charging; 1968 - bool connected = wacom_wac->hid_data.bat_connected; 1969 - bool powered = wacom_wac->hid_data.ps_connected; 1970 - 1971 - wacom_notify_battery(wacom_wac, status, capacity, 1972 - charging, connected, powered); 1973 - } 1974 - } 1975 - 1976 1908 static void wacom_wac_pad_report(struct hid_device *hdev, 1977 1909 struct hid_report *report) 1978 1910 { ··· 1998 1968 break; 1999 1969 case HID_DG_INRANGE: 2000 1970 wacom_map_usage(input, usage, field, EV_KEY, BTN_TOOL_PEN, 0); 2001 - break; 2002 - case HID_DG_BATTERYSTRENGTH: 2003 - features->quirks |= WACOM_QUIRK_BATTERY; 2004 1971 break; 2005 1972 case HID_DG_INVERT: 2006 1973 wacom_map_usage(input, usage, field, EV_KEY, ··· 2071 2044 if (!(features->quirks & WACOM_QUIRK_SENSE)) 2072 2045 wacom_wac->hid_data.sense_state = value; 2073 2046 return; 2074 - case HID_DG_BATTERYSTRENGTH: 2075 - if (value == 0) { 2076 - wacom_wac->hid_data.bat_status = POWER_SUPPLY_STATUS_UNKNOWN; 2077 - } 2078 - else { 2079 - value = value * 100 / (field->logical_maximum - field->logical_minimum); 2080 - wacom_wac->hid_data.battery_capacity = value; 2081 - wacom_wac->hid_data.bat_connected = 1; 2082 - wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO; 2083 - } 2084 - break; 2085 2047 case HID_DG_INVERT: 2086 2048 wacom_wac->hid_data.invert_state = value; 2087 2049 return; ··· 2205 2189 2206 2190 input_sync(input); 2207 2191 } 2208 - 2209 - wacom_wac_pad_battery_report(hdev, report); 2210 2192 2211 2193 if (!prox) { 2212 2194 wacom_wac->tool[0] = 0; ··· 2427 2413 if (WACOM_DIRECT_DEVICE(field)) 2428 2414 features->device_type |= WACOM_DEVICETYPE_DIRECT; 2429 2415 2430 - if (WACOM_PAD_FIELD(field)) 2416 + /* usage tests must precede field tests */ 2417 + if (WACOM_BATTERY_USAGE(usage)) 2418 + wacom_wac_battery_usage_mapping(hdev, field, usage); 2419 + else if (WACOM_PAD_FIELD(field)) 2431 2420 wacom_wac_pad_usage_mapping(hdev, field, usage); 2432 2421 else if (WACOM_PEN_FIELD(field)) 2433 2422 wacom_wac_pen_usage_mapping(hdev, field, usage); ··· 2449 2432 if (value > field->logical_maximum || value < field->logical_minimum) 2450 2433 return; 2451 2434 2452 - if (WACOM_PAD_FIELD(field)) { 2453 - wacom_wac_pad_battery_event(hdev, field, usage, value); 2454 - if (wacom->wacom_wac.pad_input) 2455 - wacom_wac_pad_event(hdev, field, usage, value); 2456 - } else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) 2435 + /* usage tests must precede field tests */ 2436 + if (WACOM_BATTERY_USAGE(usage)) 2437 + wacom_wac_battery_event(hdev, field, usage, value); 2438 + else if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input) 2439 + wacom_wac_pad_event(hdev, field, usage, value); 2440 + else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) 2457 2441 wacom_wac_pen_event(hdev, field, usage, value); 2458 2442 else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input) 2459 2443 wacom_wac_finger_event(hdev, field, usage, value); ··· 2488 2470 if (wacom_wac->features.type != HID_GENERIC) 2489 2471 return; 2490 2472 2473 + wacom_wac_battery_pre_report(hdev, report); 2474 + 2491 2475 if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input) 2492 2476 wacom_wac_pad_pre_report(hdev, report); 2493 2477 else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) ··· 2509 2489 if (report->type != HID_INPUT_REPORT) 2510 2490 return; 2511 2491 2512 - if (WACOM_PAD_FIELD(field)) { 2513 - wacom_wac_pad_battery_report(hdev, report); 2514 - if (wacom->wacom_wac.pad_input) 2515 - wacom_wac_pad_report(hdev, report); 2516 - } else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) 2492 + wacom_wac_battery_report(hdev, report); 2493 + 2494 + if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input) 2495 + wacom_wac_pad_report(hdev, report); 2496 + else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) 2517 2497 wacom_wac_pen_report(hdev, report); 2518 2498 else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input) 2519 2499 wacom_wac_finger_report(hdev, report);
+4
drivers/hid/wacom_wac.h
··· 153 153 #define WACOM_HID_WT_X (WACOM_HID_UP_WACOMTOUCH | 0x130) 154 154 #define WACOM_HID_WT_Y (WACOM_HID_UP_WACOMTOUCH | 0x131) 155 155 156 + #define WACOM_BATTERY_USAGE(f) (((f)->hid == HID_DG_BATTERYSTRENGTH) || \ 157 + ((f)->hid == WACOM_HID_WD_BATTERY_CHARGING) || \ 158 + ((f)->hid == WACOM_HID_WD_BATTERY_LEVEL)) 159 + 156 160 #define WACOM_PAD_FIELD(f) (((f)->physical == HID_DG_TABLETFUNCTIONKEY) || \ 157 161 ((f)->physical == WACOM_HID_WD_DIGITIZERFNKEYS) || \ 158 162 ((f)->physical == WACOM_HID_WD_DIGITIZERINFO))