Lines Matching +full:abs +full:- +full:fuzz

1 // SPDX-License-Identifier: GPL-2.0-only
6 * Copyright (c) 2012-2013 Google (c)
7 * Copyright (c) 2013-2014 Red Hat Inc.
25 #include <linux/fixp-arith.h>
28 #include "hid-ids.h"
39 "Disable Tap-To-Click mode reporting for touchpads (only on the K400 currently).");
41 /* Define a non-zero software ID to identify our own requests */
84 /* Convenience constant to check for any high-res support. */
128 u8 params[HIDPP_REPORT_VERY_LONG_MAX_LENGTH - 4U];
134 u8 params[HIDPP_REPORT_VERY_LONG_MAX_LENGTH - 4U];
165 * struct hidpp_scroll_counter - Utility class for processing high-resolution
169 * @remainder: counts the number of high-resolution units moved since the last
170 * low-resolution event (REL_WHEEL or REL_HWHEEL) was sent. Should
172 * @direction: direction of last movement (1 or -1)
247 switch (hidpp_report->report_id) { in __hidpp_send_report()
255 fields_count = hidpp->very_long_report_length; in __hidpp_send_report()
258 return -ENODEV; in __hidpp_send_report()
265 hidpp_report->device_index = 0xff; in __hidpp_send_report()
267 if (hidpp->quirks & HIDPP_QUIRK_FORCE_OUTPUT_REPORTS) { in __hidpp_send_report()
270 ret = hid_hw_raw_request(hdev, hidpp_report->report_id, in __hidpp_send_report()
275 return ret == fields_count ? 0 : -1; in __hidpp_send_report()
281 * Must be called with hidpp->send_mutex locked
284 * - success on 0
285 * - negative error means transport error
286 * - positive value means protocol error
294 __must_hold(&hidpp->send_mutex); in __do_hidpp_send_message_sync()
296 hidpp->send_receive_buf = response; in __do_hidpp_send_message_sync()
297 hidpp->answer_available = false; in __do_hidpp_send_message_sync()
305 ret = __hidpp_send_report(hidpp->hid_dev, message); in __do_hidpp_send_message_sync()
312 if (!wait_event_timeout(hidpp->wait, hidpp->answer_available, in __do_hidpp_send_message_sync()
316 return -ETIMEDOUT; in __do_hidpp_send_message_sync()
319 if (response->report_id == REPORT_ID_HIDPP_SHORT && in __do_hidpp_send_message_sync()
320 response->rap.sub_id == HIDPP_ERROR) { in __do_hidpp_send_message_sync()
321 ret = response->rap.params[1]; in __do_hidpp_send_message_sync()
326 if ((response->report_id == REPORT_ID_HIDPP_LONG || in __do_hidpp_send_message_sync()
327 response->report_id == REPORT_ID_HIDPP_VERY_LONG) && in __do_hidpp_send_message_sync()
328 response->fap.feature_index == HIDPP20_ERROR) { in __do_hidpp_send_message_sync()
329 ret = response->fap.params[1]; in __do_hidpp_send_message_sync()
351 mutex_lock(&hidpp->send_mutex); in hidpp_send_message_sync()
359 } while (--max_retries); in hidpp_send_message_sync()
361 mutex_unlock(&hidpp->send_mutex); in hidpp_send_message_sync()
380 if (param_count > sizeof(message->fap.params)) { in hidpp_send_fap_command_sync()
381 hid_dbg(hidpp->hid_dev, in hidpp_send_fap_command_sync()
384 (unsigned long long) sizeof(message->fap.params)); in hidpp_send_fap_command_sync()
385 return -EINVAL; in hidpp_send_fap_command_sync()
390 return -ENOMEM; in hidpp_send_fap_command_sync()
392 if (param_count > (HIDPP_REPORT_LONG_LENGTH - 4)) in hidpp_send_fap_command_sync()
393 message->report_id = REPORT_ID_HIDPP_VERY_LONG; in hidpp_send_fap_command_sync()
395 message->report_id = REPORT_ID_HIDPP_LONG; in hidpp_send_fap_command_sync()
396 message->fap.feature_index = feat_index; in hidpp_send_fap_command_sync()
397 message->fap.funcindex_clientid = funcindex_clientid | LINUX_KERNEL_SW_ID; in hidpp_send_fap_command_sync()
398 memcpy(&message->fap.params, params, param_count); in hidpp_send_fap_command_sync()
421 !(hidpp_dev->supported_reports & HIDPP_REPORT_SHORT_SUPPORTED)) in hidpp_send_rap_command_sync()
426 max_count = HIDPP_REPORT_SHORT_LENGTH - 4; in hidpp_send_rap_command_sync()
429 max_count = HIDPP_REPORT_LONG_LENGTH - 4; in hidpp_send_rap_command_sync()
432 max_count = hidpp_dev->very_long_report_length - 4; in hidpp_send_rap_command_sync()
435 return -EINVAL; in hidpp_send_rap_command_sync()
439 return -EINVAL; in hidpp_send_rap_command_sync()
443 return -ENOMEM; in hidpp_send_rap_command_sync()
444 message->report_id = report_id; in hidpp_send_rap_command_sync()
445 message->rap.sub_id = sub_id; in hidpp_send_rap_command_sync()
446 message->rap.reg_address = reg_address; in hidpp_send_rap_command_sync()
447 memcpy(&message->rap.params, params, param_count); in hidpp_send_rap_command_sync()
457 return (answer->fap.feature_index == question->fap.feature_index) && in hidpp_match_answer()
458 (answer->fap.funcindex_clientid == question->fap.funcindex_clientid); in hidpp_match_answer()
464 return ((answer->rap.sub_id == HIDPP_ERROR) || in hidpp_match_error()
465 (answer->fap.feature_index == HIDPP20_ERROR)) && in hidpp_match_error()
466 (answer->fap.funcindex_clientid == question->fap.feature_index) && in hidpp_match_error()
467 (answer->fap.params[0] == question->fap.funcindex_clientid); in hidpp_match_error()
473 return (hidpp->wireless_feature_index && in hidpp_report_is_connect_event()
474 (report->fap.feature_index == hidpp->wireless_feature_index)) || in hidpp_report_is_connect_event()
475 ((report->report_id == REPORT_ID_HIDPP_SHORT) && in hidpp_report_is_connect_event()
476 (report->rap.sub_id == 0x41)); in hidpp_report_is_connect_event()
512 struct hid_device *hdev = hidpp->hid_dev; in hidpp_update_usb_wireless_status()
515 if (!(hidpp->quirks & HIDPP_QUIRK_WIRELESS_STATUS)) in hidpp_update_usb_wireless_status()
520 intf = to_usb_interface(hdev->dev.parent); in hidpp_update_usb_wireless_status()
521 usb_set_wireless_status(intf, hidpp->battery.online ? in hidpp_update_usb_wireless_status()
527 * hidpp_scroll_counter_handle_scroll() - Send high- and low-resolution scroll
528 * events given a high-resolution wheel
532 * @hi_res_value: the movement of the wheel, in the mouse's high-resolution
535 * Given a high-resolution movement, this function converts the movement into
536 * fractions of 120 and emits high-resolution scroll events for the input
538 * emit low-resolution scroll events when appropriate for
539 * backwards-compatibility with userspace input libraries.
548 hi_res_value = hi_res_value * 120/counter->wheel_multiplier; in hidpp_scroll_counter_handle_scroll()
551 remainder = counter->remainder; in hidpp_scroll_counter_handle_scroll()
552 direction = hi_res_value > 0 ? 1 : -1; in hidpp_scroll_counter_handle_scroll()
555 previous = counter->last_time; in hidpp_scroll_counter_handle_scroll()
556 counter->last_time = now; in hidpp_scroll_counter_handle_scroll()
563 if (now - previous > 1000000000 || direction != counter->direction) in hidpp_scroll_counter_handle_scroll()
566 counter->direction = direction; in hidpp_scroll_counter_handle_scroll()
570 * after slow movement, so we want the threshold for low-res events to in hidpp_scroll_counter_handle_scroll()
574 if (abs(remainder) >= 60) { in hidpp_scroll_counter_handle_scroll()
576 * is half-way to the next detent (i.e. scroll 1 detent after a in hidpp_scroll_counter_handle_scroll()
582 low_res_value = (hi_res_value > 0 ? 1 : -1); in hidpp_scroll_counter_handle_scroll()
584 remainder -= low_res_value * 120; in hidpp_scroll_counter_handle_scroll()
586 counter->remainder = remainder; in hidpp_scroll_counter_handle_scroll()
589 /* -------------------------------------------------------------------------- */
591 /* -------------------------------------------------------------------------- */
599 * hidpp10_set_register - Modify a HID++ 1.0 register.
651 /* On HID++ 1.0 devices, high-res scroll was called "scrolling acceleration". */
731 hidpp->battery.level = in hidpp10_query_battery_status()
734 hidpp->battery.status = status; in hidpp10_query_battery_status()
736 hidpp->battery.online = status == POWER_SUPPLY_STATUS_DISCHARGING || in hidpp10_query_battery_status()
783 hidpp->battery.capacity = response.rap.params[0]; in hidpp10_query_battery_mileage()
785 hidpp->battery.status = status; in hidpp10_query_battery_mileage()
787 hidpp->battery.online = status == POWER_SUPPLY_STATUS_DISCHARGING || in hidpp10_query_battery_mileage()
799 if (report->report_id != REPORT_ID_HIDPP_SHORT) in hidpp10_battery_event()
802 switch (report->rap.sub_id) { in hidpp10_battery_event()
804 capacity = hidpp->battery.capacity; in hidpp10_battery_event()
805 level = hidpp10_battery_status_map_level(report->rawbytes[1]); in hidpp10_battery_event()
806 status = hidpp10_battery_status_map_status(report->rawbytes[2]); in hidpp10_battery_event()
809 capacity = report->rap.params[0]; in hidpp10_battery_event()
810 level = hidpp->battery.level; in hidpp10_battery_event()
811 status = hidpp10_battery_mileage_map_status(report->rawbytes[3]); in hidpp10_battery_event()
817 changed = capacity != hidpp->battery.capacity || in hidpp10_battery_event()
818 level != hidpp->battery.level || in hidpp10_battery_event()
819 status != hidpp->battery.status; in hidpp10_battery_event()
822 hidpp->battery.online = status == POWER_SUPPLY_STATUS_DISCHARGING || in hidpp10_battery_event()
826 hidpp->battery.level = level; in hidpp10_battery_event()
827 hidpp->battery.status = status; in hidpp10_battery_event()
828 if (hidpp->battery.ps) in hidpp10_battery_event()
829 power_supply_changed(hidpp->battery.ps); in hidpp10_battery_event()
899 struct hid_device *hdev = hidpp->hid_dev; in hidpp_unifying_init()
908 snprintf(hdev->uniq, sizeof(hdev->uniq), "%4phD", &serial); in hidpp_unifying_init()
909 dbg_hid("HID++ Unifying: Got serial: %s\n", hdev->uniq); in hidpp_unifying_init()
913 return -EIO; in hidpp_unifying_init()
915 snprintf(hdev->name, sizeof(hdev->name), "%s", name); in hidpp_unifying_init()
922 /* -------------------------------------------------------------------------- */
924 /* -------------------------------------------------------------------------- */
947 return -ENOENT; in hidpp_root_get_feature()
968 hidpp->protocol_major = 1; in hidpp_root_get_protocol_version()
969 hidpp->protocol_minor = 0; in hidpp_root_get_protocol_version()
975 return -EIO; in hidpp_root_get_protocol_version()
978 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", in hidpp_root_get_protocol_version()
980 return -EPROTO; in hidpp_root_get_protocol_version()
986 hid_err(hidpp->hid_dev, "%s: ping mismatch 0x%02x != 0x%02x\n", in hidpp_root_get_protocol_version()
988 return -EPROTO; in hidpp_root_get_protocol_version()
991 hidpp->protocol_major = response.rap.params[0]; in hidpp_root_get_protocol_version()
992 hidpp->protocol_minor = response.rap.params[1]; in hidpp_root_get_protocol_version()
995 if (!hidpp->connected_once) { in hidpp_root_get_protocol_version()
996 hid_info(hidpp->hid_dev, "HID++ %u.%u device connected.\n", in hidpp_root_get_protocol_version()
997 hidpp->protocol_major, hidpp->protocol_minor); in hidpp_root_get_protocol_version()
998 hidpp->connected_once = true; in hidpp_root_get_protocol_version()
1000 hid_dbg(hidpp->hid_dev, "HID++ %u.%u device connected.\n", in hidpp_root_get_protocol_version()
1001 hidpp->protocol_major, hidpp->protocol_minor); in hidpp_root_get_protocol_version()
1005 /* -------------------------------------------------------------------------- */
1007 /* -------------------------------------------------------------------------- */
1037 struct hid_device *hdev = hidpp->hid_dev; in hidpp_serial_init()
1045 snprintf(hdev->uniq, sizeof(hdev->uniq), "%4phD", &serial); in hidpp_serial_init()
1046 dbg_hid("HID++ DeviceInformation: Got serial: %s\n", hdev->uniq); in hidpp_serial_init()
1051 /* -------------------------------------------------------------------------- */
1053 /* -------------------------------------------------------------------------- */
1071 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", in hidpp_devicenametype_get_count()
1073 return -EPROTO; in hidpp_devicenametype_get_count()
1095 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", in hidpp_devicenametype_get_device_name()
1097 return -EPROTO; in hidpp_devicenametype_get_device_name()
1104 count = hidpp->very_long_report_length - 4; in hidpp_devicenametype_get_device_name()
1107 count = HIDPP_REPORT_LONG_LENGTH - 4; in hidpp_devicenametype_get_device_name()
1110 count = HIDPP_REPORT_SHORT_LENGTH - 4; in hidpp_devicenametype_get_device_name()
1113 return -EPROTO; in hidpp_devicenametype_get_device_name()
1150 __name_length - index); in hidpp_get_device_name()
1164 /* -------------------------------------------------------------------------- */
1166 /* -------------------------------------------------------------------------- */
1253 return -EIO; in hidpp20_batterylevel_get_battery_capacity()
1255 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", in hidpp20_batterylevel_get_battery_capacity()
1257 return -EPROTO; in hidpp20_batterylevel_get_battery_capacity()
1281 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", in hidpp20_batterylevel_get_battery_info()
1283 return -EPROTO; in hidpp20_batterylevel_get_battery_info()
1292 hidpp->capabilities |= HIDPP_CAPABILITY_BATTERY_LEVEL_STATUS; in hidpp20_batterylevel_get_battery_info()
1294 hidpp->capabilities |= HIDPP_CAPABILITY_BATTERY_MILEAGE; in hidpp20_batterylevel_get_battery_info()
1304 if (hidpp->battery.feature_index == 0xff) { in hidpp20_query_battery_info_1000()
1307 &hidpp->battery.feature_index); in hidpp20_query_battery_info_1000()
1313 hidpp->battery.feature_index, in hidpp20_query_battery_info_1000()
1320 hidpp->battery.feature_index); in hidpp20_query_battery_info_1000()
1324 hidpp->battery.status = status; in hidpp20_query_battery_info_1000()
1325 hidpp->battery.capacity = capacity; in hidpp20_query_battery_info_1000()
1326 hidpp->battery.level = level; in hidpp20_query_battery_info_1000()
1328 hidpp->battery.online = status == POWER_SUPPLY_STATUS_DISCHARGING || in hidpp20_query_battery_info_1000()
1341 if (report->fap.feature_index != hidpp->battery.feature_index || in hidpp20_battery_event_1000()
1342 report->fap.funcindex_clientid != EVENT_BATTERY_LEVEL_STATUS_BROADCAST) in hidpp20_battery_event_1000()
1345 status = hidpp20_batterylevel_map_status_capacity(report->fap.params, in hidpp20_battery_event_1000()
1351 hidpp->battery.online = status == POWER_SUPPLY_STATUS_DISCHARGING || in hidpp20_battery_event_1000()
1354 changed = capacity != hidpp->battery.capacity || in hidpp20_battery_event_1000()
1355 level != hidpp->battery.level || in hidpp20_battery_event_1000()
1356 status != hidpp->battery.status; in hidpp20_battery_event_1000()
1359 hidpp->battery.level = level; in hidpp20_battery_event_1000()
1360 hidpp->battery.capacity = capacity; in hidpp20_battery_event_1000()
1361 hidpp->battery.status = status; in hidpp20_battery_event_1000()
1362 if (hidpp->battery.ps) in hidpp20_battery_event_1000()
1363 power_supply_changed(hidpp->battery.ps); in hidpp20_battery_event_1000()
1369 /* -------------------------------------------------------------------------- */
1371 /* -------------------------------------------------------------------------- */
1436 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", in hidpp20_battery_get_battery_voltage()
1438 return -EPROTO; in hidpp20_battery_get_battery_voltage()
1443 hidpp->capabilities |= HIDPP_CAPABILITY_BATTERY_VOLTAGE; in hidpp20_battery_get_battery_voltage()
1480 return ARRAY_SIZE(voltages) - i; in hidpp20_map_battery_capacity()
1491 if (hidpp->battery.voltage_feature_index == 0xff) { in hidpp20_query_battery_voltage_info()
1493 &hidpp->battery.voltage_feature_index); in hidpp20_query_battery_voltage_info()
1499 hidpp->battery.voltage_feature_index, in hidpp20_query_battery_voltage_info()
1505 hidpp->battery.status = status; in hidpp20_query_battery_voltage_info()
1506 hidpp->battery.voltage = voltage; in hidpp20_query_battery_voltage_info()
1507 hidpp->battery.capacity = hidpp20_map_battery_capacity(hidpp->hid_dev, in hidpp20_query_battery_voltage_info()
1509 hidpp->battery.level = level; in hidpp20_query_battery_voltage_info()
1510 hidpp->battery.charge_type = charge_type; in hidpp20_query_battery_voltage_info()
1511 hidpp->battery.online = status != POWER_SUPPLY_STATUS_NOT_CHARGING; in hidpp20_query_battery_voltage_info()
1522 if (report->fap.feature_index != hidpp->battery.voltage_feature_index || in hidpp20_battery_voltage_event()
1523 report->fap.funcindex_clientid != EVENT_BATTERY_VOLTAGE_STATUS_BROADCAST) in hidpp20_battery_voltage_event()
1526 status = hidpp20_battery_map_status_voltage(report->fap.params, &voltage, in hidpp20_battery_voltage_event()
1529 hidpp->battery.online = status != POWER_SUPPLY_STATUS_NOT_CHARGING; in hidpp20_battery_voltage_event()
1531 if (voltage != hidpp->battery.voltage || status != hidpp->battery.status) { in hidpp20_battery_voltage_event()
1532 hidpp->battery.voltage = voltage; in hidpp20_battery_voltage_event()
1533 hidpp->battery.capacity = hidpp20_map_battery_capacity(hidpp->hid_dev, in hidpp20_battery_voltage_event()
1535 hidpp->battery.status = status; in hidpp20_battery_voltage_event()
1536 hidpp->battery.level = level; in hidpp20_battery_voltage_event()
1537 hidpp->battery.charge_type = charge_type; in hidpp20_battery_voltage_event()
1538 if (hidpp->battery.ps) in hidpp20_battery_voltage_event()
1539 power_supply_changed(hidpp->battery.ps); in hidpp20_battery_voltage_event()
1544 /* -------------------------------------------------------------------------- */
1546 /* -------------------------------------------------------------------------- */
1570 if (hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_LEVEL_STATUS || in hidpp20_unifiedbattery_get_capabilities()
1571 hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_PERCENTAGE) { in hidpp20_unifiedbattery_get_capabilities()
1581 return -EIO; in hidpp20_unifiedbattery_get_capabilities()
1583 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", in hidpp20_unifiedbattery_get_capabilities()
1585 return -EPROTO; in hidpp20_unifiedbattery_get_capabilities()
1598 hidpp->capabilities |= HIDPP_CAPABILITY_BATTERY_PERCENTAGE; in hidpp20_unifiedbattery_get_capabilities()
1599 hidpp->battery.supported_levels_1004 = 0; in hidpp20_unifiedbattery_get_capabilities()
1601 hidpp->capabilities |= HIDPP_CAPABILITY_BATTERY_LEVEL_STATUS; in hidpp20_unifiedbattery_get_capabilities()
1602 hidpp->battery.supported_levels_1004 = params[0]; in hidpp20_unifiedbattery_get_capabilities()
1627 hid_info(hidpp->hid_dev, "%s: charging error", in hidpp20_unifiedbattery_map_status()
1628 hidpp->name); in hidpp20_unifiedbattery_map_status()
1642 battery_level &= hidpp->battery.supported_levels_1004; in hidpp20_unifiedbattery_map_level()
1671 return -EIO; in hidpp20_unifiedbattery_get_status()
1673 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", in hidpp20_unifiedbattery_get_status()
1675 return -EPROTO; in hidpp20_unifiedbattery_get_status()
1693 if (hidpp->battery.feature_index == 0xff) { in hidpp20_query_battery_info_1004()
1696 &hidpp->battery.feature_index); in hidpp20_query_battery_info_1004()
1702 hidpp->battery.feature_index); in hidpp20_query_battery_info_1004()
1707 hidpp->battery.feature_index, in hidpp20_query_battery_info_1004()
1714 hidpp->capabilities |= HIDPP_CAPABILITY_UNIFIED_BATTERY; in hidpp20_query_battery_info_1004()
1715 hidpp->battery.capacity = state_of_charge; in hidpp20_query_battery_info_1004()
1716 hidpp->battery.status = status; in hidpp20_query_battery_info_1004()
1717 hidpp->battery.level = level; in hidpp20_query_battery_info_1004()
1718 hidpp->battery.online = true; in hidpp20_query_battery_info_1004()
1727 u8 *params = (u8 *)report->fap.params; in hidpp20_battery_event_1004()
1731 if (report->fap.feature_index != hidpp->battery.feature_index || in hidpp20_battery_event_1004()
1732 report->fap.funcindex_clientid != EVENT_UNIFIED_BATTERY_STATUS_EVENT) in hidpp20_battery_event_1004()
1739 changed = status != hidpp->battery.status || in hidpp20_battery_event_1004()
1740 (state_of_charge != hidpp->battery.capacity && in hidpp20_battery_event_1004()
1741 hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_PERCENTAGE) || in hidpp20_battery_event_1004()
1742 (level != hidpp->battery.level && in hidpp20_battery_event_1004()
1743 hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_LEVEL_STATUS); in hidpp20_battery_event_1004()
1746 hidpp->battery.capacity = state_of_charge; in hidpp20_battery_event_1004()
1747 hidpp->battery.status = status; in hidpp20_battery_event_1004()
1748 hidpp->battery.level = level; in hidpp20_battery_event_1004()
1749 if (hidpp->battery.ps) in hidpp20_battery_event_1004()
1750 power_supply_changed(hidpp->battery.ps); in hidpp20_battery_event_1004()
1756 /* -------------------------------------------------------------------------- */
1758 /* -------------------------------------------------------------------------- */
1781 val->intval = hidpp->battery.status; in hidpp_battery_get_property()
1784 val->intval = hidpp->battery.capacity; in hidpp_battery_get_property()
1787 val->intval = hidpp->battery.level; in hidpp_battery_get_property()
1790 val->intval = POWER_SUPPLY_SCOPE_DEVICE; in hidpp_battery_get_property()
1793 val->intval = hidpp->battery.online; in hidpp_battery_get_property()
1796 if (!strncmp(hidpp->name, "Logitech ", 9)) in hidpp_battery_get_property()
1797 val->strval = hidpp->name + 9; in hidpp_battery_get_property()
1799 val->strval = hidpp->name; in hidpp_battery_get_property()
1802 val->strval = "Logitech"; in hidpp_battery_get_property()
1805 val->strval = hidpp->hid_dev->uniq; in hidpp_battery_get_property()
1809 val->intval = hidpp->battery.voltage * 1000; in hidpp_battery_get_property()
1812 val->intval = hidpp->battery.charge_type; in hidpp_battery_get_property()
1815 ret = -EINVAL; in hidpp_battery_get_property()
1822 /* -------------------------------------------------------------------------- */
1824 /* -------------------------------------------------------------------------- */
1834 /* -------------------------------------------------------------------------- */
1836 /* -------------------------------------------------------------------------- */
1851 …tControl/blob/acd972be0468e039b93aae81221f20a54d2d60f7/src/devices/logitech_g633_g933_935.c#L44-L52 in hidpp20_map_adc_measurement_1f20_capacity()
1878 return ARRAY_SIZE(voltages) - i; in hidpp20_map_adc_measurement_1f20_capacity()
1931 hid_dbg(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", in hidpp20_get_adc_measurement_1f20()
1942 if (hidpp->battery.adc_measurement_feature_index == 0xff) { in hidpp20_query_adc_measurement_info_1f20()
1946 &hidpp->battery.adc_measurement_feature_index); in hidpp20_query_adc_measurement_info_1f20()
1950 hidpp->capabilities |= HIDPP_CAPABILITY_ADC_MEASUREMENT; in hidpp20_query_adc_measurement_info_1f20()
1953 hidpp->battery.online = hidpp20_get_adc_measurement_1f20(hidpp, in hidpp20_query_adc_measurement_info_1f20()
1954 hidpp->battery.adc_measurement_feature_index, in hidpp20_query_adc_measurement_info_1f20()
1955 &hidpp->battery.status, in hidpp20_query_adc_measurement_info_1f20()
1956 &hidpp->battery.voltage); in hidpp20_query_adc_measurement_info_1f20()
1957 hidpp->battery.capacity = hidpp20_map_adc_measurement_1f20_capacity(hidpp->hid_dev, in hidpp20_query_adc_measurement_info_1f20()
1958 hidpp->battery.voltage); in hidpp20_query_adc_measurement_info_1f20()
1970 if (report->fap.feature_index != hidpp->battery.adc_measurement_feature_index || in hidpp20_adc_measurement_event_1f20()
1971 report->fap.funcindex_clientid != EVENT_ADC_MEASUREMENT_STATUS_BROADCAST) in hidpp20_adc_measurement_event_1f20()
1974 status = hidpp20_map_adc_measurement_1f20(report->fap.params, &voltage); in hidpp20_adc_measurement_event_1f20()
1976 hidpp->battery.online = status != POWER_SUPPLY_STATUS_UNKNOWN; in hidpp20_adc_measurement_event_1f20()
1978 if (voltage != hidpp->battery.voltage || status != hidpp->battery.status) { in hidpp20_adc_measurement_event_1f20()
1979 hidpp->battery.status = status; in hidpp20_adc_measurement_event_1f20()
1980 hidpp->battery.voltage = voltage; in hidpp20_adc_measurement_event_1f20()
1981 hidpp->battery.capacity = hidpp20_map_adc_measurement_1f20_capacity(hidpp->hid_dev, voltage); in hidpp20_adc_measurement_event_1f20()
1982 if (hidpp->battery.ps) in hidpp20_adc_measurement_event_1f20()
1983 power_supply_changed(hidpp->battery.ps); in hidpp20_adc_measurement_event_1f20()
1989 /* -------------------------------------------------------------------------- */
1990 /* 0x2120: Hi-resolution scrolling */
1991 /* -------------------------------------------------------------------------- */
2021 /* -------------------------------------------------------------------------- */
2023 /* -------------------------------------------------------------------------- */
2051 hid_warn(hidpp->hid_dev, in hidpp_hrw_get_wheel_capability()
2078 /* -------------------------------------------------------------------------- */
2080 /* -------------------------------------------------------------------------- */
2096 if (hidpp->battery.feature_index == 0xff) { in hidpp_solar_request_battery_event()
2099 &hidpp->battery.solar_feature_index); in hidpp_solar_request_battery_event()
2105 hidpp->battery.solar_feature_index, in hidpp_solar_request_battery_event()
2109 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", in hidpp_solar_request_battery_event()
2111 return -EPROTO; in hidpp_solar_request_battery_event()
2116 hidpp->capabilities |= HIDPP_CAPABILITY_BATTERY_MILEAGE; in hidpp_solar_request_battery_event()
2128 function = report->fap.funcindex_clientid; in hidpp_solar_battery_event()
2131 if (report->fap.feature_index != hidpp->battery.solar_feature_index || in hidpp_solar_battery_event()
2137 capacity = report->fap.params[0]; in hidpp_solar_battery_event()
2141 lux = (report->fap.params[1] << 8) | report->fap.params[2]; in hidpp_solar_battery_event()
2149 if (capacity < hidpp->battery.capacity) in hidpp_solar_battery_event()
2159 hidpp->battery.online = true; in hidpp_solar_battery_event()
2160 if (capacity != hidpp->battery.capacity || in hidpp_solar_battery_event()
2161 status != hidpp->battery.status) { in hidpp_solar_battery_event()
2162 hidpp->battery.capacity = capacity; in hidpp_solar_battery_event()
2163 hidpp->battery.status = status; in hidpp_solar_battery_event()
2164 if (hidpp->battery.ps) in hidpp_solar_battery_event()
2165 power_supply_changed(hidpp->battery.ps); in hidpp_solar_battery_event()
2171 /* -------------------------------------------------------------------------- */
2173 /* -------------------------------------------------------------------------- */
2187 * send a set state command to the device by reading the current items->state
2199 CMD_TOUCHPAD_FW_ITEMS_SET, &items->state, 1, &response); in hidpp_touchpad_fw_items_set()
2202 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", in hidpp_touchpad_fw_items_set()
2204 return -EPROTO; in hidpp_touchpad_fw_items_set()
2209 items->presence = params[0]; in hidpp_touchpad_fw_items_set()
2210 items->desired_state = params[1]; in hidpp_touchpad_fw_items_set()
2211 items->state = params[2]; in hidpp_touchpad_fw_items_set()
2212 items->persistent = params[3]; in hidpp_touchpad_fw_items_set()
2217 /* -------------------------------------------------------------------------- */
2219 /* -------------------------------------------------------------------------- */
2272 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", in hidpp_touchpad_get_raw_info()
2274 return -EPROTO; in hidpp_touchpad_get_raw_info()
2279 raw_info->x_size = get_unaligned_be16(&params[0]); in hidpp_touchpad_get_raw_info()
2280 raw_info->y_size = get_unaligned_be16(&params[2]); in hidpp_touchpad_get_raw_info()
2281 raw_info->z_range = params[4]; in hidpp_touchpad_get_raw_info()
2282 raw_info->area_range = params[5]; in hidpp_touchpad_get_raw_info()
2283 raw_info->maxcontacts = params[7]; in hidpp_touchpad_get_raw_info()
2284 raw_info->origin = params[8]; in hidpp_touchpad_get_raw_info()
2286 raw_info->res = get_unaligned_be16(&params[13]) * 2 / 51; in hidpp_touchpad_get_raw_info()
2299 * bit 0 - enable raw in hidpp_touchpad_set_raw_report_state()
2300 * bit 1 - 16bit Z, no area in hidpp_touchpad_set_raw_report_state()
2301 * bit 2 - enhanced sensitivity in hidpp_touchpad_set_raw_report_state()
2302 * bit 3 - width, height (4 bits each) instead of area in hidpp_touchpad_set_raw_report_state()
2303 * bit 4 - send raw + gestures (degrades smoothness) in hidpp_touchpad_set_raw_report_state()
2304 * remaining bits - reserved in hidpp_touchpad_set_raw_report_state()
2318 finger->x = x_m << 6 | data[1]; in hidpp_touchpad_touch_event()
2319 finger->y = y_m << 6 | data[3]; in hidpp_touchpad_touch_event()
2321 finger->contact_type = data[0] >> 6; in hidpp_touchpad_touch_event()
2322 finger->contact_status = data[2] >> 6; in hidpp_touchpad_touch_event()
2324 finger->z = data[4]; in hidpp_touchpad_touch_event()
2325 finger->area = data[5]; in hidpp_touchpad_touch_event()
2326 finger->finger_id = data[6] >> 4; in hidpp_touchpad_touch_event()
2333 raw_xy->end_of_frame = data[8] & 0x01; in hidpp_touchpad_raw_xy_event()
2334 raw_xy->spurious_flag = (data[8] >> 1) & 0x01; in hidpp_touchpad_raw_xy_event()
2335 raw_xy->finger_count = data[15] & 0x0f; in hidpp_touchpad_raw_xy_event()
2336 raw_xy->button = (data[8] >> 2) & 0x01; in hidpp_touchpad_raw_xy_event()
2338 if (raw_xy->finger_count) { in hidpp_touchpad_raw_xy_event()
2339 hidpp_touchpad_touch_event(&data[2], &raw_xy->fingers[0]); in hidpp_touchpad_raw_xy_event()
2340 hidpp_touchpad_touch_event(&data[9], &raw_xy->fingers[1]); in hidpp_touchpad_raw_xy_event()
2344 /* -------------------------------------------------------------------------- */
2346 /* -------------------------------------------------------------------------- */
2377 #define HIDPP_FF_EFFECTID_NONE -1
2378 #define HIDPP_FF_EFFECTID_AUTOCENTER -2
2418 -1
2425 -1
2447 for (i = 0; i < data->num_effects; i++) in hidpp_ff_find_effect()
2448 if (data->effect_ids[i] == effect_id) in hidpp_ff_find_effect()
2457 struct hidpp_ff_private_data *data = wd->data; in hidpp_ff_work_handler()
2463 switch (wd->effect_id) { in hidpp_ff_work_handler()
2465 wd->params[0] = data->slot_autocenter; in hidpp_ff_work_handler()
2472 wd->params[0] = hidpp_ff_find_effect(data, wd->effect_id); in hidpp_ff_work_handler()
2477 ret = hidpp_send_fap_command_sync(data->hidpp, data->feature_index, in hidpp_ff_work_handler()
2478 wd->command, wd->params, wd->size, &response); in hidpp_ff_work_handler()
2481 hid_err(data->hidpp->hid_dev, "Failed to send command to device!\n"); in hidpp_ff_work_handler()
2486 switch (wd->command) { in hidpp_ff_work_handler()
2489 if (slot > 0 && slot <= data->num_effects) { in hidpp_ff_work_handler()
2490 if (wd->effect_id >= 0) in hidpp_ff_work_handler()
2492 data->effect_ids[slot-1] = wd->effect_id; in hidpp_ff_work_handler()
2493 else if (wd->effect_id >= HIDPP_FF_EFFECTID_AUTOCENTER) in hidpp_ff_work_handler()
2495 data->slot_autocenter = slot; in hidpp_ff_work_handler()
2499 if (wd->effect_id >= 0) in hidpp_ff_work_handler()
2501 data->effect_ids[wd->params[0]-1] = -1; in hidpp_ff_work_handler()
2502 else if (wd->effect_id >= HIDPP_FF_EFFECTID_AUTOCENTER) in hidpp_ff_work_handler()
2504 data->slot_autocenter = 0; in hidpp_ff_work_handler()
2507 data->gain = (wd->params[0] << 8) + wd->params[1]; in hidpp_ff_work_handler()
2510 data->range = (wd->params[0] << 8) + wd->params[1]; in hidpp_ff_work_handler()
2518 atomic_dec(&data->workqueue_size); in hidpp_ff_work_handler()
2528 return -ENOMEM; in hidpp_ff_queue_work()
2530 INIT_WORK(&wd->work, hidpp_ff_work_handler); in hidpp_ff_queue_work()
2532 wd->data = data; in hidpp_ff_queue_work()
2533 wd->effect_id = effect_id; in hidpp_ff_queue_work()
2534 wd->command = command; in hidpp_ff_queue_work()
2535 wd->size = size; in hidpp_ff_queue_work()
2536 memcpy(wd->params, params, size); in hidpp_ff_queue_work()
2538 s = atomic_inc_return(&data->workqueue_size); in hidpp_ff_queue_work()
2539 queue_work(data->wq, &wd->work); in hidpp_ff_queue_work()
2543 …hid_warn(data->hidpp->hid_dev, "Force feedback command queue contains %d commands, causing substan… in hidpp_ff_queue_work()
2550 struct hidpp_ff_private_data *data = dev->ff->private; in hidpp_ff_upload_effect()
2556 params[2] = effect->replay.length >> 8; in hidpp_ff_upload_effect()
2557 params[3] = effect->replay.length & 255; in hidpp_ff_upload_effect()
2558 params[4] = effect->replay.delay >> 8; in hidpp_ff_upload_effect()
2559 params[5] = effect->replay.delay & 255; in hidpp_ff_upload_effect()
2561 switch (effect->type) { in hidpp_ff_upload_effect()
2563 force = (effect->u.constant.level * fixp_sin16((effect->direction * 360) >> 16)) >> 15; in hidpp_ff_upload_effect()
2567 params[8] = effect->u.constant.envelope.attack_level >> 7; in hidpp_ff_upload_effect()
2568 params[9] = effect->u.constant.envelope.attack_length >> 8; in hidpp_ff_upload_effect()
2569 params[10] = effect->u.constant.envelope.attack_length & 255; in hidpp_ff_upload_effect()
2570 params[11] = effect->u.constant.envelope.fade_level >> 7; in hidpp_ff_upload_effect()
2571 params[12] = effect->u.constant.envelope.fade_length >> 8; in hidpp_ff_upload_effect()
2572 params[13] = effect->u.constant.envelope.fade_length & 255; in hidpp_ff_upload_effect()
2575 effect->u.constant.level, in hidpp_ff_upload_effect()
2576 effect->direction, force); in hidpp_ff_upload_effect()
2578 effect->u.constant.envelope.attack_level, in hidpp_ff_upload_effect()
2579 effect->u.constant.envelope.attack_length, in hidpp_ff_upload_effect()
2580 effect->u.constant.envelope.fade_level, in hidpp_ff_upload_effect()
2581 effect->u.constant.envelope.fade_length); in hidpp_ff_upload_effect()
2585 switch (effect->u.periodic.waveform) { in hidpp_ff_upload_effect()
2602 …hid_err(data->hidpp->hid_dev, "Unexpected periodic waveform type %i!\n", effect->u.periodic.wavefo… in hidpp_ff_upload_effect()
2603 return -EINVAL; in hidpp_ff_upload_effect()
2605 force = (effect->u.periodic.magnitude * fixp_sin16((effect->direction * 360) >> 16)) >> 15; in hidpp_ff_upload_effect()
2606 params[6] = effect->u.periodic.magnitude >> 8; in hidpp_ff_upload_effect()
2607 params[7] = effect->u.periodic.magnitude & 255; in hidpp_ff_upload_effect()
2608 params[8] = effect->u.periodic.offset >> 8; in hidpp_ff_upload_effect()
2609 params[9] = effect->u.periodic.offset & 255; in hidpp_ff_upload_effect()
2610 params[10] = effect->u.periodic.period >> 8; in hidpp_ff_upload_effect()
2611 params[11] = effect->u.periodic.period & 255; in hidpp_ff_upload_effect()
2612 params[12] = effect->u.periodic.phase >> 8; in hidpp_ff_upload_effect()
2613 params[13] = effect->u.periodic.phase & 255; in hidpp_ff_upload_effect()
2614 params[14] = effect->u.periodic.envelope.attack_level >> 7; in hidpp_ff_upload_effect()
2615 params[15] = effect->u.periodic.envelope.attack_length >> 8; in hidpp_ff_upload_effect()
2616 params[16] = effect->u.periodic.envelope.attack_length & 255; in hidpp_ff_upload_effect()
2617 params[17] = effect->u.periodic.envelope.fade_level >> 7; in hidpp_ff_upload_effect()
2618 params[18] = effect->u.periodic.envelope.fade_length >> 8; in hidpp_ff_upload_effect()
2619 params[19] = effect->u.periodic.envelope.fade_length & 255; in hidpp_ff_upload_effect()
2622 effect->u.periodic.magnitude, effect->direction, in hidpp_ff_upload_effect()
2623 effect->u.periodic.offset, in hidpp_ff_upload_effect()
2624 effect->u.periodic.period, in hidpp_ff_upload_effect()
2625 effect->u.periodic.phase); in hidpp_ff_upload_effect()
2627 effect->u.periodic.envelope.attack_level, in hidpp_ff_upload_effect()
2628 effect->u.periodic.envelope.attack_length, in hidpp_ff_upload_effect()
2629 effect->u.periodic.envelope.fade_level, in hidpp_ff_upload_effect()
2630 effect->u.periodic.envelope.fade_length); in hidpp_ff_upload_effect()
2635 force = (effect->u.ramp.start_level * fixp_sin16((effect->direction * 360) >> 16)) >> 15; in hidpp_ff_upload_effect()
2638 force = (effect->u.ramp.end_level * fixp_sin16((effect->direction * 360) >> 16)) >> 15; in hidpp_ff_upload_effect()
2641 params[10] = effect->u.ramp.envelope.attack_level >> 7; in hidpp_ff_upload_effect()
2642 params[11] = effect->u.ramp.envelope.attack_length >> 8; in hidpp_ff_upload_effect()
2643 params[12] = effect->u.ramp.envelope.attack_length & 255; in hidpp_ff_upload_effect()
2644 params[13] = effect->u.ramp.envelope.fade_level >> 7; in hidpp_ff_upload_effect()
2645 params[14] = effect->u.ramp.envelope.fade_length >> 8; in hidpp_ff_upload_effect()
2646 params[15] = effect->u.ramp.envelope.fade_length & 255; in hidpp_ff_upload_effect()
2648 dbg_hid("Uploading ramp force level=%d -> %d in dir %d = %d\n", in hidpp_ff_upload_effect()
2649 effect->u.ramp.start_level, in hidpp_ff_upload_effect()
2650 effect->u.ramp.end_level, in hidpp_ff_upload_effect()
2651 effect->direction, force); in hidpp_ff_upload_effect()
2653 effect->u.ramp.envelope.attack_level, in hidpp_ff_upload_effect()
2654 effect->u.ramp.envelope.attack_length, in hidpp_ff_upload_effect()
2655 effect->u.ramp.envelope.fade_level, in hidpp_ff_upload_effect()
2656 effect->u.ramp.envelope.fade_length); in hidpp_ff_upload_effect()
2662 params[1] = HIDPP_FF_CONDITION_CMDS[effect->type - FF_SPRING]; in hidpp_ff_upload_effect()
2663 params[6] = effect->u.condition[0].left_saturation >> 9; in hidpp_ff_upload_effect()
2664 params[7] = (effect->u.condition[0].left_saturation >> 1) & 255; in hidpp_ff_upload_effect()
2665 params[8] = effect->u.condition[0].left_coeff >> 8; in hidpp_ff_upload_effect()
2666 params[9] = effect->u.condition[0].left_coeff & 255; in hidpp_ff_upload_effect()
2667 params[10] = effect->u.condition[0].deadband >> 9; in hidpp_ff_upload_effect()
2668 params[11] = (effect->u.condition[0].deadband >> 1) & 255; in hidpp_ff_upload_effect()
2669 params[12] = effect->u.condition[0].center >> 8; in hidpp_ff_upload_effect()
2670 params[13] = effect->u.condition[0].center & 255; in hidpp_ff_upload_effect()
2671 params[14] = effect->u.condition[0].right_coeff >> 8; in hidpp_ff_upload_effect()
2672 params[15] = effect->u.condition[0].right_coeff & 255; in hidpp_ff_upload_effect()
2673 params[16] = effect->u.condition[0].right_saturation >> 9; in hidpp_ff_upload_effect()
2674 params[17] = (effect->u.condition[0].right_saturation >> 1) & 255; in hidpp_ff_upload_effect()
2677 HIDPP_FF_CONDITION_NAMES[effect->type - FF_SPRING], in hidpp_ff_upload_effect()
2678 effect->u.condition[0].left_coeff, in hidpp_ff_upload_effect()
2679 effect->u.condition[0].left_saturation, in hidpp_ff_upload_effect()
2680 effect->u.condition[0].right_coeff, in hidpp_ff_upload_effect()
2681 effect->u.condition[0].right_saturation); in hidpp_ff_upload_effect()
2683 effect->u.condition[0].deadband, in hidpp_ff_upload_effect()
2684 effect->u.condition[0].center); in hidpp_ff_upload_effect()
2687 hid_err(data->hidpp->hid_dev, "Unexpected force type %i!\n", effect->type); in hidpp_ff_upload_effect()
2688 return -EINVAL; in hidpp_ff_upload_effect()
2691 return hidpp_ff_queue_work(data, effect->id, HIDPP_FF_DOWNLOAD_EFFECT, params, size); in hidpp_ff_upload_effect()
2696 struct hidpp_ff_private_data *data = dev->ff->private; in hidpp_ff_playback()
2708 struct hidpp_ff_private_data *data = dev->ff->private; in hidpp_ff_erase_effect()
2718 struct hidpp_ff_private_data *data = dev->ff->private; in hidpp_ff_set_autocenter()
2740 struct hidpp_ff_private_data *data = dev->ff->private; in hidpp_ff_set_gain()
2756 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); in hidpp_ff_range_show()
2757 struct input_dev *idev = hidinput->input; in hidpp_ff_range_show()
2758 struct hidpp_ff_private_data *data = idev->ff->private; in hidpp_ff_range_show()
2760 return scnprintf(buf, PAGE_SIZE, "%u\n", data->range); in hidpp_ff_range_show()
2766 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); in hidpp_ff_range_store()
2767 struct input_dev *idev = hidinput->input; in hidpp_ff_range_store()
2768 struct hidpp_ff_private_data *data = idev->ff->private; in hidpp_ff_range_store()
2777 hidpp_ff_queue_work(data, -1, HIDPP_FF_SET_APERTURE, params, ARRAY_SIZE(params)); in hidpp_ff_range_store()
2786 struct hidpp_ff_private_data *data = ff->private; in hidpp_ff_destroy()
2787 struct hid_device *hid = data->hidpp->hid_dev; in hidpp_ff_destroy()
2791 device_remove_file(&hid->dev, &dev_attr_range); in hidpp_ff_destroy()
2792 destroy_workqueue(data->wq); in hidpp_ff_destroy()
2793 kfree(data->effect_ids); in hidpp_ff_destroy()
2799 struct hid_device *hid = hidpp->hid_dev; in hidpp_ff_init()
2805 int error, j, num_slots = data->num_effects; in hidpp_ff_init()
2810 return -ENODEV; in hidpp_ff_init()
2813 if (list_empty(&hid->inputs)) { in hidpp_ff_init()
2815 return -ENODEV; in hidpp_ff_init()
2817 hidinput = list_entry(hid->inputs.next, struct hid_input, list); in hidpp_ff_init()
2818 dev = hidinput->input; in hidpp_ff_init()
2822 return -EINVAL; in hidpp_ff_init()
2826 udesc = &(hid_to_usb_dev(hid)->descriptor); in hidpp_ff_init()
2827 bcdDevice = le16_to_cpu(udesc->bcdDevice); in hidpp_ff_init()
2832 set_bit(hidpp_ff_effects[j], dev->ffbit); in hidpp_ff_init()
2835 set_bit(hidpp_ff_effects_v2[j], dev->ffbit); in hidpp_ff_init()
2849 return -ENOMEM; in hidpp_ff_init()
2850 data->effect_ids = kcalloc(num_slots, sizeof(int), GFP_KERNEL); in hidpp_ff_init()
2851 if (!data->effect_ids) { in hidpp_ff_init()
2853 return -ENOMEM; in hidpp_ff_init()
2855 data->wq = create_singlethread_workqueue("hidpp-ff-sendqueue"); in hidpp_ff_init()
2856 if (!data->wq) { in hidpp_ff_init()
2857 kfree(data->effect_ids); in hidpp_ff_init()
2859 return -ENOMEM; in hidpp_ff_init()
2862 data->hidpp = hidpp; in hidpp_ff_init()
2863 data->version = version; in hidpp_ff_init()
2865 data->effect_ids[j] = -1; in hidpp_ff_init()
2867 ff = dev->ff; in hidpp_ff_init()
2868 ff->private = data; in hidpp_ff_init()
2870 ff->upload = hidpp_ff_upload_effect; in hidpp_ff_init()
2871 ff->erase = hidpp_ff_erase_effect; in hidpp_ff_init()
2872 ff->playback = hidpp_ff_playback; in hidpp_ff_init()
2873 ff->set_gain = hidpp_ff_set_gain; in hidpp_ff_init()
2874 ff->set_autocenter = hidpp_ff_set_autocenter; in hidpp_ff_init()
2875 ff->destroy = hidpp_ff_destroy; in hidpp_ff_init()
2878 error = device_create_file(&(hidpp->hid_dev->dev), &dev_attr_range); in hidpp_ff_init()
2880 hid_warn(hidpp->hid_dev, "Unable to create sysfs interface for \"range\", errno %d!\n", error); in hidpp_ff_init()
2883 atomic_set(&data->workqueue_size, 0); in hidpp_ff_init()
2897 /* -------------------------------------------------------------------------- */
2899 /* -------------------------------------------------------------------------- */
2917 return -1; in wtp_input_mapping()
2923 struct wtp_data *wd = hidpp->private_data; in wtp_populate_input()
2925 __set_bit(EV_ABS, input_dev->evbit); in wtp_populate_input()
2926 __set_bit(EV_KEY, input_dev->evbit); in wtp_populate_input()
2927 __clear_bit(EV_REL, input_dev->evbit); in wtp_populate_input()
2928 __clear_bit(EV_LED, input_dev->evbit); in wtp_populate_input()
2930 input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, wd->x_size, 0, 0); in wtp_populate_input()
2931 input_abs_set_res(input_dev, ABS_MT_POSITION_X, wd->resolution); in wtp_populate_input()
2932 input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, wd->y_size, 0, 0); in wtp_populate_input()
2933 input_abs_set_res(input_dev, ABS_MT_POSITION_Y, wd->resolution); in wtp_populate_input()
2940 if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) in wtp_populate_input()
2943 __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); in wtp_populate_input()
2945 input_mt_init_slots(input_dev, wd->maxcontacts, INPUT_MT_POINTER | in wtp_populate_input()
2952 struct wtp_data *wd = hidpp->private_data; in wtp_touch_event()
2955 if (!touch_report->finger_id || touch_report->contact_type) in wtp_touch_event()
2959 slot = input_mt_get_slot_by_key(hidpp->input, touch_report->finger_id); in wtp_touch_event()
2961 input_mt_slot(hidpp->input, slot); in wtp_touch_event()
2962 input_mt_report_slot_state(hidpp->input, MT_TOOL_FINGER, in wtp_touch_event()
2963 touch_report->contact_status); in wtp_touch_event()
2964 if (touch_report->contact_status) { in wtp_touch_event()
2965 input_event(hidpp->input, EV_ABS, ABS_MT_POSITION_X, in wtp_touch_event()
2966 touch_report->x); in wtp_touch_event()
2967 input_event(hidpp->input, EV_ABS, ABS_MT_POSITION_Y, in wtp_touch_event()
2968 wd->flip_y ? wd->y_size - touch_report->y : in wtp_touch_event()
2969 touch_report->y); in wtp_touch_event()
2970 input_event(hidpp->input, EV_ABS, ABS_MT_PRESSURE, in wtp_touch_event()
2971 touch_report->area); in wtp_touch_event()
2981 wtp_touch_event(hidpp, &(raw->fingers[i])); in wtp_send_raw_xy_event()
2983 if (raw->end_of_frame && in wtp_send_raw_xy_event()
2984 !(hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS)) in wtp_send_raw_xy_event()
2985 input_event(hidpp->input, EV_KEY, BTN_LEFT, raw->button); in wtp_send_raw_xy_event()
2987 if (raw->end_of_frame || raw->finger_count <= 2) { in wtp_send_raw_xy_event()
2988 input_mt_sync_frame(hidpp->input); in wtp_send_raw_xy_event()
2989 input_sync(hidpp->input); in wtp_send_raw_xy_event()
2995 struct wtp_data *wd = hidpp->private_data; in wtp_mouse_raw_xy_event()
3021 .finger_count = wd->maxcontacts, in wtp_mouse_raw_xy_event()
3035 struct wtp_data *wd = hidpp->private_data; in wtp_raw_event()
3039 if (!wd || !hidpp->input) in wtp_raw_event()
3049 if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) { in wtp_raw_event()
3050 input_event(hidpp->input, EV_KEY, BTN_LEFT, in wtp_raw_event()
3052 input_event(hidpp->input, EV_KEY, BTN_RIGHT, in wtp_raw_event()
3054 input_sync(hidpp->input); in wtp_raw_event()
3063 if ((report->fap.feature_index != wd->mt_feature_index) || in wtp_raw_event()
3064 (report->fap.funcindex_clientid != EVENT_TOUCHPAD_RAW_XY)) in wtp_raw_event()
3077 struct wtp_data *wd = hidpp->private_data; in wtp_get_config()
3082 &wd->mt_feature_index); in wtp_get_config()
3087 ret = hidpp_touchpad_get_raw_info(hidpp, wd->mt_feature_index, in wtp_get_config()
3092 wd->x_size = raw_info.x_size; in wtp_get_config()
3093 wd->y_size = raw_info.y_size; in wtp_get_config()
3094 wd->maxcontacts = raw_info.maxcontacts; in wtp_get_config()
3095 wd->flip_y = raw_info.origin == TOUCHPAD_RAW_XY_ORIGIN_LOWER_LEFT; in wtp_get_config()
3096 wd->resolution = raw_info.res; in wtp_get_config()
3097 if (!wd->resolution) in wtp_get_config()
3098 wd->resolution = WTP_MANUAL_RESOLUTION; in wtp_get_config()
3108 wd = devm_kzalloc(&hdev->dev, sizeof(struct wtp_data), in wtp_allocate()
3111 return -ENOMEM; in wtp_allocate()
3113 hidpp->private_data = wd; in wtp_allocate()
3121 struct wtp_data *wd = hidpp->private_data; in wtp_connect()
3124 if (!wd->x_size) { in wtp_connect()
3132 return hidpp_touchpad_set_raw_report_state(hidpp, wd->mt_feature_index, in wtp_connect()
3136 /* ------------------------------------------------------------------------- */
3138 /* ------------------------------------------------------------------------- */
3149 * forward button -> Super_R
3150 * backward button -> Super_L+'d' (press only)
3151 * middle button -> 1st time: Alt_L+SuperL+XF86TouchpadOff (press only)
3152 * 2nd time: left-click (press only)
3153 * NB: press-only means that when the button is pressed, the
3161 * - it never sends a keyboard key event
3162 * - for the three mouse button it sends:
3203 if (!hidpp->input) { in m560_raw_event()
3205 return -EINVAL; in m560_raw_event()
3219 * data[1] = device-id in m560_raw_event()
3221 * data[5] = 0xaf -> middle in m560_raw_event()
3222 * 0xb0 -> forward in m560_raw_event()
3223 * 0xae -> backward in m560_raw_event()
3224 * 0x00 -> release all in m560_raw_event()
3230 input_report_key(hidpp->input, BTN_MIDDLE, 1); in m560_raw_event()
3233 input_report_key(hidpp->input, BTN_FORWARD, 1); in m560_raw_event()
3236 input_report_key(hidpp->input, BTN_BACK, 1); in m560_raw_event()
3239 input_report_key(hidpp->input, BTN_BACK, 0); in m560_raw_event()
3240 input_report_key(hidpp->input, BTN_FORWARD, 0); in m560_raw_event()
3241 input_report_key(hidpp->input, BTN_MIDDLE, 0); in m560_raw_event()
3247 input_sync(hidpp->input); in m560_raw_event()
3261 input_report_key(hidpp->input, BTN_LEFT, in m560_raw_event()
3263 input_report_key(hidpp->input, BTN_RIGHT, in m560_raw_event()
3267 input_report_rel(hidpp->input, REL_HWHEEL, -1); in m560_raw_event()
3268 input_report_rel(hidpp->input, REL_HWHEEL_HI_RES, in m560_raw_event()
3269 -120); in m560_raw_event()
3271 input_report_rel(hidpp->input, REL_HWHEEL, 1); in m560_raw_event()
3272 input_report_rel(hidpp->input, REL_HWHEEL_HI_RES, in m560_raw_event()
3277 input_report_rel(hidpp->input, REL_X, v); in m560_raw_event()
3280 input_report_rel(hidpp->input, REL_Y, v); in m560_raw_event()
3284 hidpp_scroll_counter_handle_scroll(hidpp->input, in m560_raw_event()
3285 &hidpp->vertical_wheel_counter, v); in m560_raw_event()
3287 input_sync(hidpp->input); in m560_raw_event()
3296 __set_bit(EV_KEY, input_dev->evbit); in m560_populate_input()
3297 __set_bit(BTN_MIDDLE, input_dev->keybit); in m560_populate_input()
3298 __set_bit(BTN_RIGHT, input_dev->keybit); in m560_populate_input()
3299 __set_bit(BTN_LEFT, input_dev->keybit); in m560_populate_input()
3300 __set_bit(BTN_BACK, input_dev->keybit); in m560_populate_input()
3301 __set_bit(BTN_FORWARD, input_dev->keybit); in m560_populate_input()
3303 __set_bit(EV_REL, input_dev->evbit); in m560_populate_input()
3304 __set_bit(REL_X, input_dev->relbit); in m560_populate_input()
3305 __set_bit(REL_Y, input_dev->relbit); in m560_populate_input()
3306 __set_bit(REL_WHEEL, input_dev->relbit); in m560_populate_input()
3307 __set_bit(REL_HWHEEL, input_dev->relbit); in m560_populate_input()
3308 __set_bit(REL_WHEEL_HI_RES, input_dev->relbit); in m560_populate_input()
3309 __set_bit(REL_HWHEEL_HI_RES, input_dev->relbit); in m560_populate_input()
3316 return -1; in m560_input_mapping()
3319 /* ------------------------------------------------------------------------- */
3321 /* ------------------------------------------------------------------------- */
3326 * tap-to-click but the setting is not remembered accross reset, annoying some
3339 struct k400_private_data *k400 = hidpp->private_data; in k400_disable_tap_to_click()
3343 if (!k400->feature_index) { in k400_disable_tap_to_click()
3346 &k400->feature_index); in k400_disable_tap_to_click()
3352 ret = hidpp_touchpad_fw_items_set(hidpp, k400->feature_index, &items); in k400_disable_tap_to_click()
3364 k400 = devm_kzalloc(&hdev->dev, sizeof(struct k400_private_data), in k400_allocate()
3367 return -ENOMEM; in k400_allocate()
3369 hidpp->private_data = k400; in k400_allocate()
3384 /* ------------------------------------------------------------------------- */
3386 /* ------------------------------------------------------------------------- */
3402 ret = hidpp_send_fap_command_sync(hidpp, data->feature_index, in g920_ff_set_autocenter()
3407 hid_warn(hidpp->hid_dev, "Failed to autocenter device!\n"); in g920_ff_set_autocenter()
3409 data->slot_autocenter = response.fap.params[0]; in g920_ff_set_autocenter()
3424 &data->feature_index); in g920_get_config()
3429 ret = hidpp_send_fap_command_sync(hidpp, data->feature_index, in g920_get_config()
3436 hid_err(hidpp->hid_dev, in g920_get_config()
3438 return -EPROTO; in g920_get_config()
3441 data->num_effects = response.fap.params[0] - HIDPP_FF_RESERVED_SLOTS; in g920_get_config()
3444 ret = hidpp_send_fap_command_sync(hidpp, data->feature_index, in g920_get_config()
3449 hid_warn(hidpp->hid_dev, "Failed to reset all forces!\n"); in g920_get_config()
3451 ret = hidpp_send_fap_command_sync(hidpp, data->feature_index, in g920_get_config()
3456 hid_warn(hidpp->hid_dev, in g920_get_config()
3459 data->range = ret ? in g920_get_config()
3463 ret = hidpp_send_fap_command_sync(hidpp, data->feature_index, in g920_get_config()
3468 hid_warn(hidpp->hid_dev, in g920_get_config()
3470 data->gain = ret ? in g920_get_config()
3478 /* -------------------------------------------------------------------------- */
3480 /* -------------------------------------------------------------------------- */
3487 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) in lg_dinovo_input_mapping()
3490 switch (usage->hid & HID_USAGE) { in lg_dinovo_input_mapping()
3498 /* -------------------------------------------------------------------------- */
3500 /* -------------------------------------------------------------------------- */
3513 if (!hidpp->input) in hidpp10_wheel_raw_event()
3514 return -EINVAL; in hidpp10_wheel_raw_event()
3525 input_report_rel(hidpp->input, REL_WHEEL, value); in hidpp10_wheel_raw_event()
3526 input_report_rel(hidpp->input, REL_WHEEL_HI_RES, value * 120); in hidpp10_wheel_raw_event()
3527 input_report_rel(hidpp->input, REL_HWHEEL, hvalue); in hidpp10_wheel_raw_event()
3528 input_report_rel(hidpp->input, REL_HWHEEL_HI_RES, hvalue * 120); in hidpp10_wheel_raw_event()
3529 input_sync(hidpp->input); in hidpp10_wheel_raw_event()
3537 __set_bit(EV_REL, input_dev->evbit); in hidpp10_wheel_populate_input()
3538 __set_bit(REL_WHEEL, input_dev->relbit); in hidpp10_wheel_populate_input()
3539 __set_bit(REL_WHEEL_HI_RES, input_dev->relbit); in hidpp10_wheel_populate_input()
3540 __set_bit(REL_HWHEEL, input_dev->relbit); in hidpp10_wheel_populate_input()
3541 __set_bit(REL_HWHEEL_HI_RES, input_dev->relbit); in hidpp10_wheel_populate_input()
3544 /* -------------------------------------------------------------------------- */
3546 /* -------------------------------------------------------------------------- */
3559 if (!hidpp->input) in hidpp10_extra_mouse_buttons_raw_event()
3560 return -EINVAL; in hidpp10_extra_mouse_buttons_raw_event()
3573 * the same usb-id show different behavior, so we handle both cases. in hidpp10_extra_mouse_buttons_raw_event()
3576 input_report_key(hidpp->input, BTN_MOUSE + i, in hidpp10_extra_mouse_buttons_raw_event()
3581 input_report_key(hidpp->input, BTN_MISC + i, in hidpp10_extra_mouse_buttons_raw_event()
3584 input_sync(hidpp->input); in hidpp10_extra_mouse_buttons_raw_event()
3591 /* BTN_MOUSE - BTN_MOUSE+7 are set already by the descriptor */ in hidpp10_extra_mouse_buttons_populate_input()
3592 __set_bit(BTN_0, input_dev->keybit); in hidpp10_extra_mouse_buttons_populate_input()
3593 __set_bit(BTN_1, input_dev->keybit); in hidpp10_extra_mouse_buttons_populate_input()
3594 __set_bit(BTN_2, input_dev->keybit); in hidpp10_extra_mouse_buttons_populate_input()
3595 __set_bit(BTN_3, input_dev->keybit); in hidpp10_extra_mouse_buttons_populate_input()
3596 __set_bit(BTN_4, input_dev->keybit); in hidpp10_extra_mouse_buttons_populate_input()
3597 __set_bit(BTN_5, input_dev->keybit); in hidpp10_extra_mouse_buttons_populate_input()
3598 __set_bit(BTN_6, input_dev->keybit); in hidpp10_extra_mouse_buttons_populate_input()
3599 __set_bit(BTN_7, input_dev->keybit); in hidpp10_extra_mouse_buttons_populate_input()
3602 /* -------------------------------------------------------------------------- */
3603 /* HID++1.0 kbds which only report 0x10xx consumer usages through sub-id 0x03 */
3604 /* -------------------------------------------------------------------------- */
3606 /* Find the consumer-page input report desc and change Maximums to 0x107f */
3625 size = *rsize - (consumer_rdesc - rdesc); in hidpp10_consumer_keys_report_fixup()
3661 hid_report_raw_event(hidpp->hid_dev, HID_INPUT_REPORT, in hidpp10_consumer_keys_raw_event()
3667 /* -------------------------------------------------------------------------- */
3668 /* High-resolution scroll wheels */
3669 /* -------------------------------------------------------------------------- */
3676 if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP20_HI_RES_WHEEL) { in hi_res_scroll_enable()
3680 } else if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP20_HI_RES_SCROLL) { in hi_res_scroll_enable()
3683 } else /* if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP10_FAST_SCROLL) */ { in hi_res_scroll_enable()
3688 hid_dbg(hidpp->hid_dev, in hi_res_scroll_enable()
3689 "Could not enable hi-res scrolling: %d\n", ret); in hi_res_scroll_enable()
3694 hid_dbg(hidpp->hid_dev, in hi_res_scroll_enable()
3699 hidpp->vertical_wheel_counter.wheel_multiplier = multiplier; in hi_res_scroll_enable()
3700 hid_dbg(hidpp->hid_dev, "wheel multiplier = %d\n", multiplier); in hi_res_scroll_enable()
3709 capabilities = hidpp->capabilities; in hidpp_initialize_hires_scroll()
3711 if (hidpp->protocol_major >= 2) { in hidpp_initialize_hires_scroll()
3717 hidpp->capabilities |= HIDPP_CAPABILITY_HIDPP20_HI_RES_WHEEL; in hidpp_initialize_hires_scroll()
3718 hid_dbg(hidpp->hid_dev, "Detected HID++ 2.0 hi-res scroll wheel\n"); in hidpp_initialize_hires_scroll()
3724 hidpp->capabilities |= HIDPP_CAPABILITY_HIDPP20_HI_RES_SCROLL; in hidpp_initialize_hires_scroll()
3725 hid_dbg(hidpp->hid_dev, "Detected HID++ 2.0 hi-res scrolling\n"); in hidpp_initialize_hires_scroll()
3729 if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_1P0) { in hidpp_initialize_hires_scroll()
3730 hidpp->capabilities |= HIDPP_CAPABILITY_HIDPP10_FAST_SCROLL; in hidpp_initialize_hires_scroll()
3731 hid_dbg(hidpp->hid_dev, "Detected HID++ 1.0 fast scroll\n"); in hidpp_initialize_hires_scroll()
3735 if (hidpp->capabilities == capabilities) in hidpp_initialize_hires_scroll()
3736 hid_dbg(hidpp->hid_dev, "Did not detect HID++ hi-res scrolling hardware support\n"); in hidpp_initialize_hires_scroll()
3740 /* -------------------------------------------------------------------------- */
3742 /* -------------------------------------------------------------------------- */
3753 if (hdev->group == HID_GROUP_LOGITECH_27MHZ_DEVICE || in hidpp_report_fixup()
3754 (hidpp->quirks & HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS)) in hidpp_report_fixup()
3769 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) in hidpp_input_mapping()
3771 else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560 && in hidpp_input_mapping()
3772 field->application != HID_GD_MOUSE) in hidpp_input_mapping()
3775 if (hdev->product == DINOVO_MINI_PRODUCT_ID) in hidpp_input_mapping()
3790 /* Ensure that Logitech G920 is not given a default fuzz/flat value */ in hidpp_input_mapped()
3791 if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { in hidpp_input_mapped()
3792 if (usage->type == EV_ABS && (usage->code == ABS_X || in hidpp_input_mapped()
3793 usage->code == ABS_Y || usage->code == ABS_Z || in hidpp_input_mapped()
3794 usage->code == ABS_RZ)) { in hidpp_input_mapped()
3795 field->application = HID_GD_MULTIAXIS; in hidpp_input_mapped()
3806 hidpp->input = input; in hidpp_populate_input()
3808 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) in hidpp_populate_input()
3810 else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560) in hidpp_populate_input()
3813 if (hidpp->quirks & HIDPP_QUIRK_HIDPP_WHEELS) in hidpp_populate_input()
3816 if (hidpp->quirks & HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS) in hidpp_populate_input()
3824 struct input_dev *input = hidinput->input; in hidpp_input_configured()
3837 struct hidpp_report *question = hidpp->send_receive_buf; in hidpp_raw_hidpp_event()
3838 struct hidpp_report *answer = hidpp->send_receive_buf; in hidpp_raw_hidpp_event()
3847 if (unlikely(mutex_is_locked(&hidpp->send_mutex))) { in hidpp_raw_hidpp_event()
3855 hidpp->answer_available = true; in hidpp_raw_hidpp_event()
3856 wake_up(&hidpp->wait); in hidpp_raw_hidpp_event()
3859 * We return 1 to hid-core to avoid forwarding the in hidpp_raw_hidpp_event()
3868 if (schedule_work(&hidpp->work) == 0) in hidpp_raw_hidpp_event()
3873 if (hidpp->hid_dev->group == HID_GROUP_LOGITECH_27MHZ_DEVICE && in hidpp_raw_hidpp_event()
3877 dev_err_ratelimited(&hidpp->hid_dev->dev, in hidpp_raw_hidpp_event()
3878 …less encryption key has been lost, your keyboard will not work unless you re-configure encryption.… in hidpp_raw_hidpp_event()
3879 dev_err_ratelimited(&hidpp->hid_dev->dev, in hidpp_raw_hidpp_event()
3880 "See: https://gitlab.freedesktop.org/jwrdegoede/logitech-27mhz-keyboard-encryption-setup/\n"); in hidpp_raw_hidpp_event()
3883 last_online = hidpp->battery.online; in hidpp_raw_hidpp_event()
3884 if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP20_BATTERY) { in hidpp_raw_hidpp_event()
3902 if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP10_BATTERY) { in hidpp_raw_hidpp_event()
3908 if (hidpp->quirks & HIDPP_QUIRK_RESET_HI_RES_SCROLL) { in hidpp_raw_hidpp_event()
3909 if (last_online == 0 && hidpp->battery.online == 1) in hidpp_raw_hidpp_event()
3910 schedule_work(&hidpp->reset_hi_res_work); in hidpp_raw_hidpp_event()
3913 if (hidpp->quirks & HIDPP_QUIRK_HIDPP_WHEELS) { in hidpp_raw_hidpp_event()
3919 if (hidpp->quirks & HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS) { in hidpp_raw_hidpp_event()
3925 if (hidpp->quirks & HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS) { in hidpp_raw_hidpp_event()
3946 if (size != hidpp->very_long_report_length) { in hidpp_raw_event()
3976 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) in hidpp_raw_event()
3978 else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560) in hidpp_raw_event()
3996 counter = &hidpp->vertical_wheel_counter; in hidpp_event()
3998 * the input device set, or high-res scroll enabling may fail. In such in hidpp_event()
4002 if (!(hidpp->capabilities & HIDPP_CAPABILITY_HI_RES_SCROLL) in hidpp_event()
4003 || value == 0 || hidpp->input == NULL in hidpp_event()
4004 || counter->wheel_multiplier == 0) in hidpp_event()
4007 hidpp_scroll_counter_handle_scroll(hidpp->input, counter, value); in hidpp_event()
4015 struct power_supply_desc *desc = &hidpp->battery.desc; in hidpp_initialize_battery()
4022 if (hidpp->battery.ps) in hidpp_initialize_battery()
4025 hidpp->battery.feature_index = 0xff; in hidpp_initialize_battery()
4026 hidpp->battery.solar_feature_index = 0xff; in hidpp_initialize_battery()
4027 hidpp->battery.voltage_feature_index = 0xff; in hidpp_initialize_battery()
4028 hidpp->battery.adc_measurement_feature_index = 0xff; in hidpp_initialize_battery()
4030 if (hidpp->protocol_major >= 2) { in hidpp_initialize_battery()
4031 if (hidpp->quirks & HIDPP_QUIRK_CLASS_K750) in hidpp_initialize_battery()
4048 hidpp->capabilities |= HIDPP_CAPABILITY_HIDPP20_BATTERY; in hidpp_initialize_battery()
4054 return -ENOENT; in hidpp_initialize_battery()
4055 hidpp->capabilities |= HIDPP_CAPABILITY_BATTERY_MILEAGE; in hidpp_initialize_battery()
4057 hidpp->capabilities |= HIDPP_CAPABILITY_BATTERY_LEVEL_STATUS; in hidpp_initialize_battery()
4059 hidpp->capabilities |= HIDPP_CAPABILITY_HIDPP10_BATTERY; in hidpp_initialize_battery()
4062 battery_props = devm_kmemdup(&hidpp->hid_dev->dev, in hidpp_initialize_battery()
4067 return -ENOMEM; in hidpp_initialize_battery()
4069 num_battery_props = ARRAY_SIZE(hidpp_battery_props) - 3; in hidpp_initialize_battery()
4071 if (hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_MILEAGE || in hidpp_initialize_battery()
4072 hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_PERCENTAGE || in hidpp_initialize_battery()
4073 hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_VOLTAGE || in hidpp_initialize_battery()
4074 hidpp->capabilities & HIDPP_CAPABILITY_ADC_MEASUREMENT) in hidpp_initialize_battery()
4078 if (hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_LEVEL_STATUS) in hidpp_initialize_battery()
4082 if (hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_VOLTAGE || in hidpp_initialize_battery()
4083 hidpp->capabilities & HIDPP_CAPABILITY_ADC_MEASUREMENT) in hidpp_initialize_battery()
4087 battery = &hidpp->battery; in hidpp_initialize_battery()
4089 n = atomic_inc_return(&battery_no) - 1; in hidpp_initialize_battery()
4090 desc->properties = battery_props; in hidpp_initialize_battery()
4091 desc->num_properties = num_battery_props; in hidpp_initialize_battery()
4092 desc->get_property = hidpp_battery_get_property; in hidpp_initialize_battery()
4093 sprintf(battery->name, "hidpp_battery_%ld", n); in hidpp_initialize_battery()
4094 desc->name = battery->name; in hidpp_initialize_battery()
4095 desc->type = POWER_SUPPLY_TYPE_BATTERY; in hidpp_initialize_battery()
4096 desc->use_for_apm = 0; in hidpp_initialize_battery()
4098 battery->ps = devm_power_supply_register(&hidpp->hid_dev->dev, in hidpp_initialize_battery()
4099 &battery->desc, in hidpp_initialize_battery()
4101 if (IS_ERR(battery->ps)) in hidpp_initialize_battery()
4102 return PTR_ERR(battery->ps); in hidpp_initialize_battery()
4104 power_supply_powers(battery->ps, &hidpp->hid_dev->dev); in hidpp_initialize_battery()
4112 struct hid_device *hdev = hidpp->hid_dev; in hidpp_non_unifying_init()
4122 snprintf(hdev->name, sizeof(hdev->name), "%s", name); in hidpp_non_unifying_init()
4143 struct input_dev *input_dev = devm_input_allocate_device(&hdev->dev); in hidpp_allocate_input()
4150 input_dev->open = hidpp_input_open; in hidpp_allocate_input()
4151 input_dev->close = hidpp_input_close; in hidpp_allocate_input()
4153 input_dev->name = hidpp->name; in hidpp_allocate_input()
4154 input_dev->phys = hdev->phys; in hidpp_allocate_input()
4155 input_dev->uniq = hdev->uniq; in hidpp_allocate_input()
4156 input_dev->id.bustype = hdev->bus; in hidpp_allocate_input()
4157 input_dev->id.vendor = hdev->vendor; in hidpp_allocate_input()
4158 input_dev->id.product = hdev->product; in hidpp_allocate_input()
4159 input_dev->id.version = hdev->version; in hidpp_allocate_input()
4160 input_dev->dev.parent = &hdev->dev; in hidpp_allocate_input()
4168 struct hid_device *hdev = hidpp->hid_dev; in hidpp_connect_event()
4176 hid_dbg(hidpp->hid_dev, "Disconnected\n"); in hidpp_connect_event()
4177 if (hidpp->battery.ps) { in hidpp_connect_event()
4178 hidpp->battery.online = false; in hidpp_connect_event()
4179 hidpp->battery.status = POWER_SUPPLY_STATUS_UNKNOWN; in hidpp_connect_event()
4180 hidpp->battery.level = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN; in hidpp_connect_event()
4181 power_supply_changed(hidpp->battery.ps); in hidpp_connect_event()
4186 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) { in hidpp_connect_event()
4190 } else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560) { in hidpp_connect_event()
4194 } else if (hidpp->quirks & HIDPP_QUIRK_CLASS_K400) { in hidpp_connect_event()
4200 if (hidpp->quirks & HIDPP_QUIRK_HIDPP_WHEELS) { in hidpp_connect_event()
4206 if (hidpp->quirks & HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS) { in hidpp_connect_event()
4212 if (hidpp->quirks & HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS) { in hidpp_connect_event()
4218 if (hidpp->protocol_major >= 2) { in hidpp_connect_event()
4222 hidpp->wireless_feature_index = feature_index; in hidpp_connect_event()
4225 if (hidpp->name == hdev->name && hidpp->protocol_major >= 2) { in hidpp_connect_event()
4228 devm_name = devm_kasprintf(&hdev->dev, GFP_KERNEL, in hidpp_connect_event()
4234 hidpp->name = devm_name; in hidpp_connect_event()
4239 if (!hid_is_usb(hidpp->hid_dev)) in hidpp_connect_event()
4243 if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP10_BATTERY) { in hidpp_connect_event()
4245 if (hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_MILEAGE) in hidpp_connect_event()
4249 } else if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP20_BATTERY) { in hidpp_connect_event()
4250 if (hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_VOLTAGE) in hidpp_connect_event()
4252 else if (hidpp->capabilities & HIDPP_CAPABILITY_UNIFIED_BATTERY) in hidpp_connect_event()
4254 else if (hidpp->capabilities & HIDPP_CAPABILITY_ADC_MEASUREMENT) in hidpp_connect_event()
4259 if (hidpp->battery.ps) in hidpp_connect_event()
4260 power_supply_changed(hidpp->battery.ps); in hidpp_connect_event()
4262 if (hidpp->capabilities & HIDPP_CAPABILITY_HI_RES_SCROLL) in hidpp_connect_event()
4265 if (!(hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) || hidpp->delayed_input) in hidpp_connect_event()
4283 hidpp->delayed_input = input; in hidpp_connect_event()
4309 re = &(hdev->report_enum[HID_OUTPUT_REPORT]); in hidpp_get_report_length()
4310 report = re->report_id_hash[id]; in hidpp_get_report_length()
4314 return report->field[0]->report_count + 1; in hidpp_get_report_length()
4349 hidpp->very_long_report_length = report_length; in hidpp_validate_device()
4365 report_list = &hdev->report_enum[HID_INPUT_REPORT].report_list; in hidpp_application_equals()
4367 return report && report->application == application; in hidpp_application_equals()
4377 hidpp = devm_kzalloc(&hdev->dev, sizeof(*hidpp), GFP_KERNEL); in hidpp_probe()
4379 return -ENOMEM; in hidpp_probe()
4381 hidpp->hid_dev = hdev; in hidpp_probe()
4382 hidpp->name = hdev->name; in hidpp_probe()
4383 hidpp->quirks = id->driver_data; in hidpp_probe()
4395 hidpp->supported_reports = hidpp_validate_device(hdev); in hidpp_probe()
4397 if (!hidpp->supported_reports) { in hidpp_probe()
4399 devm_kfree(&hdev->dev, hidpp); in hidpp_probe()
4403 if (id->group == HID_GROUP_LOGITECH_27MHZ_DEVICE && in hidpp_probe()
4405 hidpp->quirks |= HIDPP_QUIRK_HIDPP_WHEELS | in hidpp_probe()
4408 if (id->group == HID_GROUP_LOGITECH_27MHZ_DEVICE && in hidpp_probe()
4410 hidpp->quirks |= HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS; in hidpp_probe()
4412 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) { in hidpp_probe()
4416 } else if (hidpp->quirks & HIDPP_QUIRK_CLASS_K400) { in hidpp_probe()
4422 INIT_WORK(&hidpp->work, hidpp_connect_event); in hidpp_probe()
4423 INIT_WORK(&hidpp->reset_hi_res_work, hidpp_reset_hi_res_handler); in hidpp_probe()
4424 mutex_init(&hidpp->send_mutex); in hidpp_probe()
4425 init_waitqueue_head(&hidpp->wait); in hidpp_probe()
4428 ret = sysfs_create_group(&hdev->dev.kobj, &ps_attribute_group); in hidpp_probe()
4431 hdev->name); in hidpp_probe()
4435 * hid subdrivers (hid-input, hidraw). This allows retrieving the dev's in hidpp_probe()
4436 * name and serial number and store these in hdev->name and hdev->uniq, in hidpp_probe()
4437 * before the hid-input and hidraw drivers expose these to userspace. in hidpp_probe()
4447 dev_err(&hdev->dev, "%s:hid_hw_open returned error:%d\n", in hidpp_probe()
4455 /* Get name + serial, store in hdev->name + hdev->uniq */ in hidpp_probe()
4456 if (id->group == HID_GROUP_LOGITECH_DJ_DEVICE) in hidpp_probe()
4461 if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) in hidpp_probe()
4474 schedule_work(&hidpp->work); in hidpp_probe()
4475 flush_work(&hidpp->work); in hidpp_probe()
4477 if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { in hidpp_probe()
4485 hid_warn(hidpp->hid_dev, in hidpp_probe()
4491 * This relies on logi_dj_ll_close() being a no-op so that DJ connection in hidpp_probe()
4502 sysfs_remove_group(&hdev->dev.kobj, &ps_attribute_group); in hidpp_probe()
4503 cancel_work_sync(&hidpp->work); in hidpp_probe()
4504 mutex_destroy(&hidpp->send_mutex); in hidpp_probe()
4515 sysfs_remove_group(&hdev->dev.kobj, &ps_attribute_group); in hidpp_remove()
4518 cancel_work_sync(&hidpp->work); in hidpp_remove()
4519 cancel_work_sync(&hidpp->reset_hi_res_work); in hidpp_remove()
4520 mutex_destroy(&hidpp->send_mutex); in hidpp_remove()
4558 { /* Keyboard MX5000 (Bluetooth-receiver in HID proxy mode) */
4561 { /* Dinovo Edge (Bluetooth-receiver in HID proxy mode) */
4564 { /* Keyboard MX5500 (Bluetooth-receiver in HID proxy mode) */
4573 { /* Keyboard LX501 (Y-RR53) */
4576 { /* Keyboard MX3000 (Y-RAM74) */
4579 { /* Keyboard MX3200 (Y-RAV80) */
4638 { /* M-RCQ142 V470 Cordless Laser Mouse over Bluetooth */
4668 { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
4672 .name = "logitech-hidpp-device",