Lines Matching +full:charger +full:- +full:thermistor
1 // SPDX-License-Identifier: GPL-2.0-or-later
10 #include <linux/input-event-codes.h>
20 #include "hid-ids.h"
26 HID_USAGE_ANDROID_PLAYPAUSE_BTN = 0xcd, /* Double-tap volume slider */
109 __le16 thermistor; member
159 struct thunderstrike_hostcmd_charger charger; member
201 * Non-trivial to uniquely identify Thunderstrike controllers at initialization
211 /* Sub-devices */
232 report->report_id = THUNDERSTRIKE_HOSTCMD_REQ_REPORT_ID; in thunderstrike_hostcmd_req_report_init()
233 report->cmd_id = cmd_id; in thunderstrike_hostcmd_req_report_init()
238 dest[0] = ('A' - 1) + (rev >> 8); in shield_strrev()
239 snprintf(&dest[1], len - 1, "%02X", 0xff & rev); in shield_strrev()
251 idev->id.bustype = hdev->bus; in shield_allocate_input_dev()
252 idev->id.vendor = hdev->vendor; in shield_allocate_input_dev()
253 idev->id.product = hdev->product; in shield_allocate_input_dev()
254 idev->id.version = hdev->version; in shield_allocate_input_dev()
255 idev->uniq = hdev->uniq; in shield_allocate_input_dev()
256 idev->name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s %s", hdev->name, in shield_allocate_input_dev()
258 if (!idev->name) in shield_allocate_input_dev()
268 return ERR_PTR(-ENOMEM); in shield_allocate_input_dev()
281 haptics = shield_allocate_input_dev(dev->hdev, "Haptics"); in shield_haptics_create()
301 struct thunderstrike_hostcmd_req_report *report = ts->req_report_dmabuf; in thunderstrike_send_hostcmd_request()
302 struct shield_device *shield_dev = &ts->base; in thunderstrike_send_hostcmd_request()
305 ret = hid_hw_raw_request(shield_dev->hdev, report->report_id, in thunderstrike_send_hostcmd_request()
306 ts->req_report_dmabuf, in thunderstrike_send_hostcmd_request()
311 hid_err(shield_dev->hdev, in thunderstrike_send_hostcmd_request()
324 report = ts->req_report_dmabuf; in thunderstrike_hostcmd_req_work_handler()
326 if (test_and_clear_bit(THUNDERSTRIKE_FW_VERSION_UPDATE, &ts->update_flags)) { in thunderstrike_hostcmd_req_work_handler()
332 if (test_and_clear_bit(THUNDERSTRIKE_LED_UPDATE, &ts->update_flags)) { in thunderstrike_hostcmd_req_work_handler()
334 report->led.update = 1; in thunderstrike_hostcmd_req_work_handler()
335 report->led.state = ts->led_value; in thunderstrike_hostcmd_req_work_handler()
339 if (test_and_clear_bit(THUNDERSTRIKE_POWER_SUPPLY_STATS_UPDATE, &ts->update_flags)) { in thunderstrike_hostcmd_req_work_handler()
349 if (test_and_clear_bit(THUNDERSTRIKE_BOARD_INFO_UPDATE, &ts->update_flags)) { in thunderstrike_hostcmd_req_work_handler()
355 if (test_and_clear_bit(THUNDERSTRIKE_HAPTICS_UPDATE, &ts->update_flags)) { in thunderstrike_hostcmd_req_work_handler()
359 report->haptics.update = 1; in thunderstrike_hostcmd_req_work_handler()
360 spin_lock_irqsave(&ts->haptics_update_lock, flags); in thunderstrike_hostcmd_req_work_handler()
361 report->haptics.motors = ts->haptics_val; in thunderstrike_hostcmd_req_work_handler()
362 spin_unlock_irqrestore(&ts->haptics_update_lock, flags); in thunderstrike_hostcmd_req_work_handler()
370 set_bit(THUNDERSTRIKE_FW_VERSION_UPDATE, &ts->update_flags); in thunderstrike_request_firmware_version()
371 schedule_work(&ts->hostcmd_req_work); in thunderstrike_request_firmware_version()
376 set_bit(THUNDERSTRIKE_BOARD_INFO_UPDATE, &ts->update_flags); in thunderstrike_request_board_info()
377 schedule_work(&ts->hostcmd_req_work); in thunderstrike_request_board_info()
386 spin_lock_irqsave(&ts->haptics_update_lock, flags); in thunderstrike_update_haptics()
387 ts->haptics_val = *motors; in thunderstrike_update_haptics()
388 spin_unlock_irqrestore(&ts->haptics_update_lock, flags); in thunderstrike_update_haptics()
390 set_bit(THUNDERSTRIKE_HAPTICS_UPDATE, &ts->update_flags); in thunderstrike_update_haptics()
391 schedule_work(&ts->hostcmd_req_work); in thunderstrike_update_haptics()
404 if (effect->type != FF_RUMBLE) in thunderstrike_play_effect()
411 motors.motor_left = effect->u.rumble.strong_magnitude / 2047; in thunderstrike_play_effect()
412 motors.motor_right = effect->u.rumble.weak_magnitude / 2047; in thunderstrike_play_effect()
423 struct hid_device *hdev = to_hid_device(led->dev->parent); in thunderstrike_led_get_brightness()
429 return ts->led_state; in thunderstrike_led_get_brightness()
435 struct hid_device *hdev = to_hid_device(led->dev->parent); in thunderstrike_led_set_brightness()
443 ts->led_value = THUNDERSTRIKE_LED_OFF; in thunderstrike_led_set_brightness()
446 ts->led_value = THUNDERSTRIKE_LED_ON; in thunderstrike_led_set_brightness()
450 set_bit(THUNDERSTRIKE_LED_UPDATE, &ts->update_flags); in thunderstrike_led_set_brightness()
451 schedule_work(&ts->hostcmd_req_work); in thunderstrike_led_set_brightness()
464 spin_lock(&ts->psy_stats_lock); in thunderstrike_battery_get_property()
465 prop_values = ts->psy_stats; in thunderstrike_battery_get_property()
466 spin_unlock(&ts->psy_stats_lock); in thunderstrike_battery_get_property()
470 val->intval = prop_values.status; in thunderstrike_battery_get_property()
473 val->intval = prop_values.charge_type; in thunderstrike_battery_get_property()
476 val->intval = 1; in thunderstrike_battery_get_property()
479 val->intval = prop_values.voltage_min; in thunderstrike_battery_get_property()
482 val->intval = 2900000; /* 2.9 V */ in thunderstrike_battery_get_property()
485 val->intval = 2200000; /* 2.2 V */ in thunderstrike_battery_get_property()
488 val->intval = prop_values.voltage_now; in thunderstrike_battery_get_property()
491 val->intval = prop_values.voltage_avg; in thunderstrike_battery_get_property()
494 val->intval = prop_values.voltage_boot; in thunderstrike_battery_get_property()
497 val->intval = prop_values.capacity; in thunderstrike_battery_get_property()
500 val->intval = POWER_SUPPLY_SCOPE_DEVICE; in thunderstrike_battery_get_property()
503 val->intval = prop_values.temp; in thunderstrike_battery_get_property()
506 val->intval = 0; /* 0 C */ in thunderstrike_battery_get_property()
509 val->intval = 400; /* 40 C */ in thunderstrike_battery_get_property()
512 val->intval = 15; /* 1.5 C */ in thunderstrike_battery_get_property()
515 val->intval = 380; /* 38 C */ in thunderstrike_battery_get_property()
518 ret = -EINVAL; in thunderstrike_battery_get_property()
527 set_bit(THUNDERSTRIKE_POWER_SUPPLY_STATS_UPDATE, &ts->update_flags); in thunderstrike_request_psy_stats()
528 schedule_work(&ts->hostcmd_req_work); in thunderstrike_request_psy_stats()
545 shield_dev->fw_version = le16_to_cpu(fw_version); in thunderstrike_parse_fw_version_payload()
547 set_bit(SHIELD_FW_VERSION_INITIALIZED, &shield_dev->initialized_flags); in thunderstrike_parse_fw_version_payload()
549 hid_dbg(shield_dev->hdev, "Thunderstrike firmware version 0x%04X\n", in thunderstrike_parse_fw_version_payload()
550 shield_dev->fw_version); in thunderstrike_parse_fw_version_payload()
560 shield_dev->board_info.revision = le16_to_cpu(board_info->revision); in thunderstrike_parse_board_info_payload()
562 u16 val = le16_to_cpu(board_info->serial[i]); in thunderstrike_parse_board_info_payload()
564 shield_dev->board_info.serial_number[2 * i] = val & 0xFF; in thunderstrike_parse_board_info_payload()
565 shield_dev->board_info.serial_number[2 * i + 1] = val >> 8; in thunderstrike_parse_board_info_payload()
567 shield_dev->board_info.serial_number[14] = '\0'; in thunderstrike_parse_board_info_payload()
569 set_bit(SHIELD_BOARD_INFO_INITIALIZED, &shield_dev->initialized_flags); in thunderstrike_parse_board_info_payload()
571 shield_strrev(board_revision_str, 4, shield_dev->board_info.revision); in thunderstrike_parse_board_info_payload()
572 hid_dbg(shield_dev->hdev, in thunderstrike_parse_board_info_payload()
574 board_revision_str, shield_dev->board_info.revision, in thunderstrike_parse_board_info_payload()
575 shield_dev->board_info.serial_number); in thunderstrike_parse_board_info_payload()
582 hid_dbg(shield_dev->hdev, in thunderstrike_parse_haptics_payload()
584 haptics->motor_left, haptics->motor_right); in thunderstrike_parse_haptics_payload()
595 ts->led_state = 0; in thunderstrike_parse_led_payload()
598 ts->led_state = 1; in thunderstrike_parse_led_payload()
602 hid_dbg(shield_dev->hdev, "Thunderstrike led HOSTCMD response, 0x%02X\n", led_state); in thunderstrike_parse_led_payload()
610 u16 hostcmd_voltage_boot = le16_to_cpu(battery->voltage_boot); in thunderstrike_parse_battery_payload()
611 u16 hostcmd_voltage_avg = le16_to_cpu(battery->voltage_avg); in thunderstrike_parse_battery_payload()
612 u16 hostcmd_voltage_min = le16_to_cpu(battery->voltage_min); in thunderstrike_parse_battery_payload()
613 u16 hostcmd_voltage_now = le16_to_cpu(battery->voltage_now); in thunderstrike_parse_battery_payload()
614 u16 hostcmd_thermistor = le16_to_cpu(battery->thermistor); in thunderstrike_parse_battery_payload()
616 struct hid_device *hdev = shield_dev->hdev; in thunderstrike_parse_battery_payload()
617 u8 capacity = battery->capacity; in thunderstrike_parse_battery_payload()
625 temp = (1378 - (int)hostcmd_thermistor) * 10 / 19; in thunderstrike_parse_battery_payload()
628 spin_lock(&ts->psy_stats_lock); in thunderstrike_parse_battery_payload()
629 ts->psy_stats.voltage_boot = voltage_boot; in thunderstrike_parse_battery_payload()
630 ts->psy_stats.voltage_avg = voltage_avg; in thunderstrike_parse_battery_payload()
631 ts->psy_stats.voltage_min = voltage_min; in thunderstrike_parse_battery_payload()
632 ts->psy_stats.voltage_now = voltage_now; in thunderstrike_parse_battery_payload()
633 ts->psy_stats.capacity = capacity; in thunderstrike_parse_battery_payload()
634 ts->psy_stats.temp = temp; in thunderstrike_parse_battery_payload()
635 spin_unlock(&ts->psy_stats_lock); in thunderstrike_parse_battery_payload()
637 set_bit(SHIELD_BATTERY_STATS_INITIALIZED, &shield_dev->initialized_flags); in thunderstrike_parse_battery_payload()
646 "Thunderstrike battery HOSTCMD response, thermistor: %u\n", in thunderstrike_parse_battery_payload()
655 struct thunderstrike_hostcmd_charger *charger) in thunderstrike_parse_charger_payload() argument
659 struct hid_device *hdev = shield_dev->hdev; in thunderstrike_parse_charger_payload()
662 switch (charger->type) { in thunderstrike_parse_charger_payload()
673 hid_warn(hdev, "Unhandled Thunderstrike charger HOSTCMD type, %u\n", in thunderstrike_parse_charger_payload()
674 charger->type); in thunderstrike_parse_charger_payload()
678 switch (charger->state) { in thunderstrike_parse_charger_payload()
683 /* Indicates charger is disconnected */ in thunderstrike_parse_charger_payload()
696 hid_warn(hdev, "Unhandled Thunderstrike charger HOSTCMD state, %u\n", in thunderstrike_parse_charger_payload()
697 charger->state); in thunderstrike_parse_charger_payload()
701 if (!charger->connected) in thunderstrike_parse_charger_payload()
704 spin_lock(&ts->psy_stats_lock); in thunderstrike_parse_charger_payload()
705 ts->psy_stats.charge_type = charge_type; in thunderstrike_parse_charger_payload()
706 ts->psy_stats.status = status; in thunderstrike_parse_charger_payload()
707 spin_unlock(&ts->psy_stats_lock); in thunderstrike_parse_charger_payload()
709 set_bit(SHIELD_CHARGER_STATE_INITIALIZED, &shield_dev->initialized_flags); in thunderstrike_parse_charger_payload()
712 "Thunderstrike charger HOSTCMD response, connected: %u, type: %u, state: %u\n", in thunderstrike_parse_charger_payload()
713 charger->connected, charger->type, charger->state); in thunderstrike_parse_charger_payload()
721 if (!test_bit(SHIELD_FW_VERSION_INITIALIZED, &shield_dev->initialized_flags)) in thunderstrike_device_init_info()
724 if (!test_bit(SHIELD_BOARD_INFO_INITIALIZED, &shield_dev->initialized_flags)) in thunderstrike_device_init_info()
727 if (!test_bit(SHIELD_BATTERY_STATS_INITIALIZED, &shield_dev->initialized_flags) || in thunderstrike_device_init_info()
728 !test_bit(SHIELD_CHARGER_STATE_INITIALIZED, &shield_dev->initialized_flags)) in thunderstrike_device_init_info()
729 thunderstrike_psy_stats_timer_handler(&ts->psy_stats_timer); in thunderstrike_device_init_info()
737 struct hid_device *hdev = shield_dev->hdev; in thunderstrike_parse_report()
739 switch (report->id) { in thunderstrike_parse_report()
745 return -EINVAL; in thunderstrike_parse_report()
751 switch (hostcmd_resp_report->cmd_id) { in thunderstrike_parse_report()
754 shield_dev, hostcmd_resp_report->fw_version); in thunderstrike_parse_report()
757 thunderstrike_parse_led_payload(shield_dev, hostcmd_resp_report->led_state); in thunderstrike_parse_report()
761 &hostcmd_resp_report->battery); in thunderstrike_parse_report()
765 shield_dev, &hostcmd_resp_report->board_info); in thunderstrike_parse_report()
769 shield_dev, &hostcmd_resp_report->motors); in thunderstrike_parse_report()
780 shield_dev, &hostcmd_resp_report->charger); in thunderstrike_parse_report()
785 hostcmd_resp_report->cmd_id); in thunderstrike_parse_report()
786 return -ENOENT; in thunderstrike_parse_report()
799 struct led_classdev *led = &ts->led_dev; in thunderstrike_led_create()
801 led->name = devm_kasprintf(&ts->base.hdev->dev, GFP_KERNEL, in thunderstrike_led_create()
802 "thunderstrike%d:blue:led", ts->id); in thunderstrike_led_create()
803 if (!led->name) in thunderstrike_led_create()
804 return -ENOMEM; in thunderstrike_led_create()
805 led->max_brightness = 1; in thunderstrike_led_create()
806 led->flags = LED_CORE_SUSPENDRESUME | LED_RETAIN_AT_SHUTDOWN; in thunderstrike_led_create()
807 led->brightness_get = &thunderstrike_led_get_brightness; in thunderstrike_led_create()
808 led->brightness_set = &thunderstrike_led_set_brightness; in thunderstrike_led_create()
810 return led_classdev_register(&ts->base.hdev->dev, led); in thunderstrike_led_create()
817 struct hid_device *hdev = shield_dev->hdev; in thunderstrike_psy_create()
825 ts->psy_stats.capacity = 100; in thunderstrike_psy_create()
826 ts->psy_stats.temp = 182; in thunderstrike_psy_create()
828 shield_dev->battery_dev.desc.properties = thunderstrike_battery_props; in thunderstrike_psy_create()
829 shield_dev->battery_dev.desc.num_properties = in thunderstrike_psy_create()
831 shield_dev->battery_dev.desc.get_property = thunderstrike_battery_get_property; in thunderstrike_psy_create()
832 shield_dev->battery_dev.desc.type = POWER_SUPPLY_TYPE_BATTERY; in thunderstrike_psy_create()
833 shield_dev->battery_dev.desc.name = in thunderstrike_psy_create()
834 devm_kasprintf(&ts->base.hdev->dev, GFP_KERNEL, in thunderstrike_psy_create()
835 "thunderstrike_%d", ts->id); in thunderstrike_psy_create()
836 if (!shield_dev->battery_dev.desc.name) in thunderstrike_psy_create()
837 return -ENOMEM; in thunderstrike_psy_create()
839 shield_dev->battery_dev.psy = power_supply_register( in thunderstrike_psy_create()
840 &hdev->dev, &shield_dev->battery_dev.desc, &psy_cfg); in thunderstrike_psy_create()
841 if (IS_ERR(shield_dev->battery_dev.psy)) { in thunderstrike_psy_create()
843 return PTR_ERR(shield_dev->battery_dev.psy); in thunderstrike_psy_create()
846 ret = power_supply_powers(shield_dev->battery_dev.psy, &hdev->dev); in thunderstrike_psy_create()
855 power_supply_unregister(shield_dev->battery_dev.psy); in thunderstrike_psy_create()
865 ts = devm_kzalloc(&hdev->dev, sizeof(*ts), GFP_KERNEL); in thunderstrike_create()
867 return ERR_PTR(-ENOMEM); in thunderstrike_create()
869 ts->req_report_dmabuf = devm_kzalloc( in thunderstrike_create()
870 &hdev->dev, THUNDERSTRIKE_HOSTCMD_REPORT_SIZE, GFP_KERNEL); in thunderstrike_create()
871 if (!ts->req_report_dmabuf) in thunderstrike_create()
872 return ERR_PTR(-ENOMEM); in thunderstrike_create()
874 shield_dev = &ts->base; in thunderstrike_create()
875 shield_dev->hdev = hdev; in thunderstrike_create()
876 shield_dev->codename = "Thunderstrike"; in thunderstrike_create()
878 spin_lock_init(&ts->haptics_update_lock); in thunderstrike_create()
879 spin_lock_init(&ts->psy_stats_lock); in thunderstrike_create()
880 INIT_WORK(&ts->hostcmd_req_work, thunderstrike_hostcmd_req_work_handler); in thunderstrike_create()
884 ts->id = ida_alloc(&thunderstrike_ida, GFP_KERNEL); in thunderstrike_create()
885 if (ts->id < 0) in thunderstrike_create()
886 return ERR_PTR(ts->id); in thunderstrike_create()
888 ts->haptics_dev = shield_haptics_create(shield_dev, thunderstrike_play_effect); in thunderstrike_create()
889 if (IS_ERR(ts->haptics_dev)) { in thunderstrike_create()
891 ret = PTR_ERR(ts->haptics_dev); in thunderstrike_create()
907 timer_setup(&ts->psy_stats_timer, thunderstrike_psy_stats_timer_handler, 0); in thunderstrike_create()
913 power_supply_unregister(shield_dev->battery_dev.psy); in thunderstrike_create()
915 if (ts->haptics_dev) in thunderstrike_create()
916 input_unregister_device(ts->haptics_dev); in thunderstrike_create()
918 ida_free(&thunderstrike_ida, ts->id); in thunderstrike_create()
924 led_classdev_unregister(&ts->led_dev); in thunderstrike_destroy()
925 power_supply_unregister(ts->base.battery_dev.psy); in thunderstrike_destroy()
926 if (ts->haptics_dev) in thunderstrike_destroy()
927 input_unregister_device(ts->haptics_dev); in thunderstrike_destroy()
928 ida_free(&thunderstrike_ida, ts->id); in thunderstrike_destroy()
936 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) in android_input_mapping()
939 switch (usage->hid & HID_USAGE) { in android_input_mapping()
974 if (test_bit(SHIELD_FW_VERSION_INITIALIZED, &shield_dev->initialized_flags)) in firmware_version_show()
975 ret = sysfs_emit(buf, "0x%04X\n", shield_dev->fw_version); in firmware_version_show()
994 if (test_bit(SHIELD_BOARD_INFO_INITIALIZED, &shield_dev->initialized_flags)) { in hardware_version_show()
995 shield_strrev(board_revision_str, 4, shield_dev->board_info.revision); in hardware_version_show()
997 shield_dev->codename, board_revision_str, in hardware_version_show()
998 shield_dev->board_info.revision); in hardware_version_show()
1016 if (test_bit(SHIELD_BOARD_INFO_INITIALIZED, &shield_dev->initialized_flags)) in serial_number_show()
1017 ret = sysfs_emit(buf, "%s\n", shield_dev->board_info.serial_number); in serial_number_show()
1054 switch (id->product) { in shield_probe()
1062 return -ENODEV; in shield_probe()
1103 del_timer_sync(&ts->psy_stats_timer); in shield_remove()
1104 cancel_work_sync(&ts->hostcmd_req_work); in shield_remove()