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()
303 struct thunderstrike_hostcmd_req_report *report = ts->req_report_dmabuf; in thunderstrike_send_hostcmd_request()
304 struct shield_device *shield_dev = &ts->base; in thunderstrike_send_hostcmd_request()
307 ret = hid_hw_raw_request(shield_dev->hdev, report->report_id, in thunderstrike_send_hostcmd_request()
308 ts->req_report_dmabuf, in thunderstrike_send_hostcmd_request()
313 hid_err(shield_dev->hdev, in thunderstrike_send_hostcmd_request()
326 report = ts->req_report_dmabuf; in thunderstrike_hostcmd_req_work_handler()
328 if (test_and_clear_bit(THUNDERSTRIKE_FW_VERSION_UPDATE, &ts->update_flags)) { in thunderstrike_hostcmd_req_work_handler()
334 if (test_and_clear_bit(THUNDERSTRIKE_LED_UPDATE, &ts->update_flags)) { in thunderstrike_hostcmd_req_work_handler()
336 report->led.update = 1; in thunderstrike_hostcmd_req_work_handler()
337 report->led.state = ts->led_value; in thunderstrike_hostcmd_req_work_handler()
341 if (test_and_clear_bit(THUNDERSTRIKE_POWER_SUPPLY_STATS_UPDATE, &ts->update_flags)) { in thunderstrike_hostcmd_req_work_handler()
351 if (test_and_clear_bit(THUNDERSTRIKE_BOARD_INFO_UPDATE, &ts->update_flags)) { in thunderstrike_hostcmd_req_work_handler()
357 if (test_and_clear_bit(THUNDERSTRIKE_HAPTICS_UPDATE, &ts->update_flags)) { in thunderstrike_hostcmd_req_work_handler()
361 report->haptics.update = 1; in thunderstrike_hostcmd_req_work_handler()
362 spin_lock_irqsave(&ts->haptics_update_lock, flags); in thunderstrike_hostcmd_req_work_handler()
363 report->haptics.motors = ts->haptics_val; in thunderstrike_hostcmd_req_work_handler()
364 spin_unlock_irqrestore(&ts->haptics_update_lock, flags); in thunderstrike_hostcmd_req_work_handler()
372 set_bit(THUNDERSTRIKE_FW_VERSION_UPDATE, &ts->update_flags); in thunderstrike_request_firmware_version()
373 schedule_work(&ts->hostcmd_req_work); in thunderstrike_request_firmware_version()
378 set_bit(THUNDERSTRIKE_BOARD_INFO_UPDATE, &ts->update_flags); in thunderstrike_request_board_info()
379 schedule_work(&ts->hostcmd_req_work); in thunderstrike_request_board_info()
388 spin_lock_irqsave(&ts->haptics_update_lock, flags); in thunderstrike_update_haptics()
389 ts->haptics_val = *motors; in thunderstrike_update_haptics()
390 spin_unlock_irqrestore(&ts->haptics_update_lock, flags); in thunderstrike_update_haptics()
392 set_bit(THUNDERSTRIKE_HAPTICS_UPDATE, &ts->update_flags); in thunderstrike_update_haptics()
393 schedule_work(&ts->hostcmd_req_work); in thunderstrike_update_haptics()
406 if (effect->type != FF_RUMBLE) in thunderstrike_play_effect()
413 motors.motor_left = effect->u.rumble.strong_magnitude / 2047; in thunderstrike_play_effect()
414 motors.motor_right = effect->u.rumble.weak_magnitude / 2047; in thunderstrike_play_effect()
425 struct hid_device *hdev = to_hid_device(led->dev->parent); in thunderstrike_led_get_brightness()
431 return ts->led_state; in thunderstrike_led_get_brightness()
437 struct hid_device *hdev = to_hid_device(led->dev->parent); in thunderstrike_led_set_brightness()
445 ts->led_value = THUNDERSTRIKE_LED_OFF; in thunderstrike_led_set_brightness()
448 ts->led_value = THUNDERSTRIKE_LED_ON; in thunderstrike_led_set_brightness()
452 set_bit(THUNDERSTRIKE_LED_UPDATE, &ts->update_flags); in thunderstrike_led_set_brightness()
453 schedule_work(&ts->hostcmd_req_work); in thunderstrike_led_set_brightness()
466 spin_lock(&ts->psy_stats_lock); in thunderstrike_battery_get_property()
467 prop_values = ts->psy_stats; in thunderstrike_battery_get_property()
468 spin_unlock(&ts->psy_stats_lock); in thunderstrike_battery_get_property()
472 val->intval = prop_values.status; in thunderstrike_battery_get_property()
475 val->intval = prop_values.charge_type; in thunderstrike_battery_get_property()
478 val->intval = 1; in thunderstrike_battery_get_property()
481 val->intval = prop_values.voltage_min; in thunderstrike_battery_get_property()
484 val->intval = 2900000; /* 2.9 V */ in thunderstrike_battery_get_property()
487 val->intval = 2200000; /* 2.2 V */ in thunderstrike_battery_get_property()
490 val->intval = prop_values.voltage_now; in thunderstrike_battery_get_property()
493 val->intval = prop_values.voltage_avg; in thunderstrike_battery_get_property()
496 val->intval = prop_values.voltage_boot; in thunderstrike_battery_get_property()
499 val->intval = prop_values.capacity; in thunderstrike_battery_get_property()
502 val->intval = POWER_SUPPLY_SCOPE_DEVICE; in thunderstrike_battery_get_property()
505 val->intval = prop_values.temp; in thunderstrike_battery_get_property()
508 val->intval = 0; /* 0 C */ in thunderstrike_battery_get_property()
511 val->intval = 400; /* 40 C */ in thunderstrike_battery_get_property()
514 val->intval = 15; /* 1.5 C */ in thunderstrike_battery_get_property()
517 val->intval = 380; /* 38 C */ in thunderstrike_battery_get_property()
520 ret = -EINVAL; in thunderstrike_battery_get_property()
529 set_bit(THUNDERSTRIKE_POWER_SUPPLY_STATS_UPDATE, &ts->update_flags); in thunderstrike_request_psy_stats()
530 schedule_work(&ts->hostcmd_req_work); in thunderstrike_request_psy_stats()
547 shield_dev->fw_version = le16_to_cpu(fw_version); in thunderstrike_parse_fw_version_payload()
549 set_bit(SHIELD_FW_VERSION_INITIALIZED, &shield_dev->initialized_flags); in thunderstrike_parse_fw_version_payload()
551 hid_dbg(shield_dev->hdev, "Thunderstrike firmware version 0x%04X\n", in thunderstrike_parse_fw_version_payload()
552 shield_dev->fw_version); in thunderstrike_parse_fw_version_payload()
562 shield_dev->board_info.revision = le16_to_cpu(board_info->revision); in thunderstrike_parse_board_info_payload()
564 u16 val = le16_to_cpu(board_info->serial[i]); in thunderstrike_parse_board_info_payload()
566 shield_dev->board_info.serial_number[2 * i] = val & 0xFF; in thunderstrike_parse_board_info_payload()
567 shield_dev->board_info.serial_number[2 * i + 1] = val >> 8; in thunderstrike_parse_board_info_payload()
569 shield_dev->board_info.serial_number[14] = '\0'; in thunderstrike_parse_board_info_payload()
571 set_bit(SHIELD_BOARD_INFO_INITIALIZED, &shield_dev->initialized_flags); in thunderstrike_parse_board_info_payload()
573 shield_strrev(board_revision_str, 4, shield_dev->board_info.revision); in thunderstrike_parse_board_info_payload()
574 hid_dbg(shield_dev->hdev, in thunderstrike_parse_board_info_payload()
576 board_revision_str, shield_dev->board_info.revision, in thunderstrike_parse_board_info_payload()
577 shield_dev->board_info.serial_number); in thunderstrike_parse_board_info_payload()
584 hid_dbg(shield_dev->hdev, in thunderstrike_parse_haptics_payload()
586 haptics->motor_left, haptics->motor_right); in thunderstrike_parse_haptics_payload()
597 ts->led_state = 0; in thunderstrike_parse_led_payload()
600 ts->led_state = 1; in thunderstrike_parse_led_payload()
604 hid_dbg(shield_dev->hdev, "Thunderstrike led HOSTCMD response, 0x%02X\n", led_state); in thunderstrike_parse_led_payload()
612 u16 hostcmd_voltage_boot = le16_to_cpu(battery->voltage_boot); in thunderstrike_parse_battery_payload()
613 u16 hostcmd_voltage_avg = le16_to_cpu(battery->voltage_avg); in thunderstrike_parse_battery_payload()
614 u16 hostcmd_voltage_min = le16_to_cpu(battery->voltage_min); in thunderstrike_parse_battery_payload()
615 u16 hostcmd_voltage_now = le16_to_cpu(battery->voltage_now); in thunderstrike_parse_battery_payload()
616 u16 hostcmd_thermistor = le16_to_cpu(battery->thermistor); in thunderstrike_parse_battery_payload()
618 struct hid_device *hdev = shield_dev->hdev; in thunderstrike_parse_battery_payload()
619 u8 capacity = battery->capacity; in thunderstrike_parse_battery_payload()
627 temp = (1378 - (int)hostcmd_thermistor) * 10 / 19; in thunderstrike_parse_battery_payload()
630 spin_lock(&ts->psy_stats_lock); in thunderstrike_parse_battery_payload()
631 ts->psy_stats.voltage_boot = voltage_boot; in thunderstrike_parse_battery_payload()
632 ts->psy_stats.voltage_avg = voltage_avg; in thunderstrike_parse_battery_payload()
633 ts->psy_stats.voltage_min = voltage_min; in thunderstrike_parse_battery_payload()
634 ts->psy_stats.voltage_now = voltage_now; in thunderstrike_parse_battery_payload()
635 ts->psy_stats.capacity = capacity; in thunderstrike_parse_battery_payload()
636 ts->psy_stats.temp = temp; in thunderstrike_parse_battery_payload()
637 spin_unlock(&ts->psy_stats_lock); in thunderstrike_parse_battery_payload()
639 set_bit(SHIELD_BATTERY_STATS_INITIALIZED, &shield_dev->initialized_flags); in thunderstrike_parse_battery_payload()
648 "Thunderstrike battery HOSTCMD response, thermistor: %u\n", in thunderstrike_parse_battery_payload()
657 struct thunderstrike_hostcmd_charger *charger) in thunderstrike_parse_charger_payload() argument
661 struct hid_device *hdev = shield_dev->hdev; in thunderstrike_parse_charger_payload()
664 switch (charger->type) { in thunderstrike_parse_charger_payload()
675 hid_warn(hdev, "Unhandled Thunderstrike charger HOSTCMD type, %u\n", in thunderstrike_parse_charger_payload()
676 charger->type); in thunderstrike_parse_charger_payload()
680 switch (charger->state) { in thunderstrike_parse_charger_payload()
685 /* Indicates charger is disconnected */ in thunderstrike_parse_charger_payload()
698 hid_warn(hdev, "Unhandled Thunderstrike charger HOSTCMD state, %u\n", in thunderstrike_parse_charger_payload()
699 charger->state); in thunderstrike_parse_charger_payload()
703 if (!charger->connected) in thunderstrike_parse_charger_payload()
706 spin_lock(&ts->psy_stats_lock); in thunderstrike_parse_charger_payload()
707 ts->psy_stats.charge_type = charge_type; in thunderstrike_parse_charger_payload()
708 ts->psy_stats.status = status; in thunderstrike_parse_charger_payload()
709 spin_unlock(&ts->psy_stats_lock); in thunderstrike_parse_charger_payload()
711 set_bit(SHIELD_CHARGER_STATE_INITIALIZED, &shield_dev->initialized_flags); in thunderstrike_parse_charger_payload()
714 "Thunderstrike charger HOSTCMD response, connected: %u, type: %u, state: %u\n", in thunderstrike_parse_charger_payload()
715 charger->connected, charger->type, charger->state); in thunderstrike_parse_charger_payload()
723 if (!test_bit(SHIELD_FW_VERSION_INITIALIZED, &shield_dev->initialized_flags)) in thunderstrike_device_init_info()
726 if (!test_bit(SHIELD_BOARD_INFO_INITIALIZED, &shield_dev->initialized_flags)) in thunderstrike_device_init_info()
729 if (!test_bit(SHIELD_BATTERY_STATS_INITIALIZED, &shield_dev->initialized_flags) || in thunderstrike_device_init_info()
730 !test_bit(SHIELD_CHARGER_STATE_INITIALIZED, &shield_dev->initialized_flags)) in thunderstrike_device_init_info()
731 thunderstrike_psy_stats_timer_handler(&ts->psy_stats_timer); in thunderstrike_device_init_info()
739 struct hid_device *hdev = shield_dev->hdev; in thunderstrike_parse_report()
741 switch (report->id) { in thunderstrike_parse_report()
747 return -EINVAL; in thunderstrike_parse_report()
753 switch (hostcmd_resp_report->cmd_id) { in thunderstrike_parse_report()
756 shield_dev, hostcmd_resp_report->fw_version); in thunderstrike_parse_report()
759 thunderstrike_parse_led_payload(shield_dev, hostcmd_resp_report->led_state); in thunderstrike_parse_report()
763 &hostcmd_resp_report->battery); in thunderstrike_parse_report()
767 shield_dev, &hostcmd_resp_report->board_info); in thunderstrike_parse_report()
771 shield_dev, &hostcmd_resp_report->motors); in thunderstrike_parse_report()
782 shield_dev, &hostcmd_resp_report->charger); in thunderstrike_parse_report()
787 hostcmd_resp_report->cmd_id); in thunderstrike_parse_report()
788 return -ENOENT; in thunderstrike_parse_report()
801 struct led_classdev *led = &ts->led_dev; in thunderstrike_led_create()
803 led->name = devm_kasprintf(&ts->base.hdev->dev, GFP_KERNEL, in thunderstrike_led_create()
804 "thunderstrike%d:blue:led", ts->id); in thunderstrike_led_create()
805 if (!led->name) in thunderstrike_led_create()
806 return -ENOMEM; in thunderstrike_led_create()
807 led->max_brightness = 1; in thunderstrike_led_create()
808 led->flags = LED_CORE_SUSPENDRESUME | LED_RETAIN_AT_SHUTDOWN; in thunderstrike_led_create()
809 led->brightness_get = &thunderstrike_led_get_brightness; in thunderstrike_led_create()
810 led->brightness_set = &thunderstrike_led_set_brightness; in thunderstrike_led_create()
812 return led_classdev_register(&ts->base.hdev->dev, led); in thunderstrike_led_create()
819 struct hid_device *hdev = shield_dev->hdev; in thunderstrike_psy_create()
827 ts->psy_stats.capacity = 100; in thunderstrike_psy_create()
828 ts->psy_stats.temp = 182; in thunderstrike_psy_create()
830 shield_dev->battery_dev.desc.properties = thunderstrike_battery_props; in thunderstrike_psy_create()
831 shield_dev->battery_dev.desc.num_properties = in thunderstrike_psy_create()
833 shield_dev->battery_dev.desc.get_property = thunderstrike_battery_get_property; in thunderstrike_psy_create()
834 shield_dev->battery_dev.desc.type = POWER_SUPPLY_TYPE_BATTERY; in thunderstrike_psy_create()
835 shield_dev->battery_dev.desc.name = in thunderstrike_psy_create()
836 devm_kasprintf(&ts->base.hdev->dev, GFP_KERNEL, in thunderstrike_psy_create()
837 "thunderstrike_%d", ts->id); in thunderstrike_psy_create()
838 if (!shield_dev->battery_dev.desc.name) in thunderstrike_psy_create()
839 return -ENOMEM; in thunderstrike_psy_create()
841 shield_dev->battery_dev.psy = power_supply_register( in thunderstrike_psy_create()
842 &hdev->dev, &shield_dev->battery_dev.desc, &psy_cfg); in thunderstrike_psy_create()
843 if (IS_ERR(shield_dev->battery_dev.psy)) { in thunderstrike_psy_create()
845 return PTR_ERR(shield_dev->battery_dev.psy); in thunderstrike_psy_create()
848 ret = power_supply_powers(shield_dev->battery_dev.psy, &hdev->dev); in thunderstrike_psy_create()
857 power_supply_unregister(shield_dev->battery_dev.psy); in thunderstrike_psy_create()
867 ts = devm_kzalloc(&hdev->dev, sizeof(*ts), GFP_KERNEL); in thunderstrike_create()
869 return ERR_PTR(-ENOMEM); in thunderstrike_create()
871 ts->req_report_dmabuf = devm_kzalloc( in thunderstrike_create()
872 &hdev->dev, THUNDERSTRIKE_HOSTCMD_REPORT_SIZE, GFP_KERNEL); in thunderstrike_create()
873 if (!ts->req_report_dmabuf) in thunderstrike_create()
874 return ERR_PTR(-ENOMEM); in thunderstrike_create()
876 shield_dev = &ts->base; in thunderstrike_create()
877 shield_dev->hdev = hdev; in thunderstrike_create()
878 shield_dev->codename = "Thunderstrike"; in thunderstrike_create()
880 spin_lock_init(&ts->haptics_update_lock); in thunderstrike_create()
881 spin_lock_init(&ts->psy_stats_lock); in thunderstrike_create()
882 INIT_WORK(&ts->hostcmd_req_work, thunderstrike_hostcmd_req_work_handler); in thunderstrike_create()
886 ts->id = ida_alloc(&thunderstrike_ida, GFP_KERNEL); in thunderstrike_create()
887 if (ts->id < 0) in thunderstrike_create()
888 return ERR_PTR(ts->id); in thunderstrike_create()
890 ts->haptics_dev = shield_haptics_create(shield_dev, thunderstrike_play_effect); in thunderstrike_create()
891 if (IS_ERR(ts->haptics_dev)) { in thunderstrike_create()
893 ret = PTR_ERR(ts->haptics_dev); in thunderstrike_create()
909 timer_setup(&ts->psy_stats_timer, thunderstrike_psy_stats_timer_handler, 0); in thunderstrike_create()
915 power_supply_unregister(shield_dev->battery_dev.psy); in thunderstrike_create()
917 if (ts->haptics_dev) in thunderstrike_create()
918 input_unregister_device(ts->haptics_dev); in thunderstrike_create()
920 ida_free(&thunderstrike_ida, ts->id); in thunderstrike_create()
926 led_classdev_unregister(&ts->led_dev); in thunderstrike_destroy()
927 power_supply_unregister(ts->base.battery_dev.psy); in thunderstrike_destroy()
928 if (ts->haptics_dev) in thunderstrike_destroy()
929 input_unregister_device(ts->haptics_dev); in thunderstrike_destroy()
930 ida_free(&thunderstrike_ida, ts->id); in thunderstrike_destroy()
938 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) in android_input_mapping()
941 switch (usage->hid & HID_USAGE) { in android_input_mapping()
976 if (test_bit(SHIELD_FW_VERSION_INITIALIZED, &shield_dev->initialized_flags)) in firmware_version_show()
977 ret = sysfs_emit(buf, "0x%04X\n", shield_dev->fw_version); in firmware_version_show()
996 if (test_bit(SHIELD_BOARD_INFO_INITIALIZED, &shield_dev->initialized_flags)) { in hardware_version_show()
997 shield_strrev(board_revision_str, 4, shield_dev->board_info.revision); in hardware_version_show()
999 shield_dev->codename, board_revision_str, in hardware_version_show()
1000 shield_dev->board_info.revision); in hardware_version_show()
1018 if (test_bit(SHIELD_BOARD_INFO_INITIALIZED, &shield_dev->initialized_flags)) in serial_number_show()
1019 ret = sysfs_emit(buf, "%s\n", shield_dev->board_info.serial_number); in serial_number_show()
1056 switch (id->product) { in shield_probe()
1064 return -ENODEV; in shield_probe()
1105 del_timer_sync(&ts->psy_stats_timer); in shield_remove()
1106 cancel_work_sync(&ts->hostcmd_req_work); in shield_remove()