Lines Matching +full:motion +full:- +full:sensors
1 // SPDX-License-Identifier: GPL-2.0-or-later
15 #include <linux/led-class-multicolor.h>
20 #include "hid-ids.h"
52 /* Calibration data for playstation motion sensors. */
147 struct input_dev *sensors; member
208 /* Motion sensors */
222 static_assert(sizeof(struct dualsense_input_report) == DS_INPUT_REPORT_USB_SIZE - 1);
308 {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1},
326 if (!memcmp(entry->mac_address, dev->mac_address, sizeof(dev->mac_address))) { in ps_devices_list_add()
327 hid_err(dev->hdev, "Duplicate device found for MAC address %pMR.\n", in ps_devices_list_add()
328 dev->mac_address); in ps_devices_list_add()
330 return -EEXIST; in ps_devices_list_add()
334 list_add_tail(&dev->list, &ps_devices_list); in ps_devices_list_add()
342 list_del(&dev->list); in ps_devices_list_remove()
354 dev->player_id = ret; in ps_device_set_player_id()
360 ida_free(&ps_player_id_allocator, dev->player_id); in ps_device_release_player_id()
362 dev->player_id = U32_MAX; in ps_device_release_player_id()
369 input_dev = devm_input_allocate_device(&hdev->dev); in ps_allocate_input_dev()
371 return ERR_PTR(-ENOMEM); in ps_allocate_input_dev()
373 input_dev->id.bustype = hdev->bus; in ps_allocate_input_dev()
374 input_dev->id.vendor = hdev->vendor; in ps_allocate_input_dev()
375 input_dev->id.product = hdev->product; in ps_allocate_input_dev()
376 input_dev->id.version = hdev->version; in ps_allocate_input_dev()
377 input_dev->uniq = hdev->uniq; in ps_allocate_input_dev()
380 input_dev->name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s %s", hdev->name, in ps_allocate_input_dev()
382 if (!input_dev->name) in ps_allocate_input_dev()
383 return ERR_PTR(-ENOMEM); in ps_allocate_input_dev()
385 input_dev->name = hdev->name; in ps_allocate_input_dev()
410 spin_lock_irqsave(&dev->lock, flags); in ps_battery_get_property()
411 battery_capacity = dev->battery_capacity; in ps_battery_get_property()
412 battery_status = dev->battery_status; in ps_battery_get_property()
413 spin_unlock_irqrestore(&dev->lock, flags); in ps_battery_get_property()
417 val->intval = battery_status; in ps_battery_get_property()
420 val->intval = 1; in ps_battery_get_property()
423 val->intval = battery_capacity; in ps_battery_get_property()
426 val->intval = POWER_SUPPLY_SCOPE_DEVICE; in ps_battery_get_property()
429 ret = -EINVAL; in ps_battery_get_property()
442 dev->battery_desc.type = POWER_SUPPLY_TYPE_BATTERY; in ps_device_register_battery()
443 dev->battery_desc.properties = ps_power_supply_props; in ps_device_register_battery()
444 dev->battery_desc.num_properties = ARRAY_SIZE(ps_power_supply_props); in ps_device_register_battery()
445 dev->battery_desc.get_property = ps_battery_get_property; in ps_device_register_battery()
446 dev->battery_desc.name = devm_kasprintf(&dev->hdev->dev, GFP_KERNEL, in ps_device_register_battery()
447 "ps-controller-battery-%pMR", dev->mac_address); in ps_device_register_battery()
448 if (!dev->battery_desc.name) in ps_device_register_battery()
449 return -ENOMEM; in ps_device_register_battery()
451 battery = devm_power_supply_register(&dev->hdev->dev, &dev->battery_desc, &battery_cfg); in ps_device_register_battery()
454 hid_err(dev->hdev, "Unable to register battery device: %d\n", ret); in ps_device_register_battery()
457 dev->battery = battery; in ps_device_register_battery()
459 ret = power_supply_powers(dev->battery, &dev->hdev->dev); in ps_device_register_battery()
461 hid_err(dev->hdev, "Unable to activate battery device: %d\n", ret); in ps_device_register_battery()
497 input_set_abs_params(gamepad, ABS_HAT0X, -1, 1, 0, 0); in ps_gamepad_create()
498 input_set_abs_params(gamepad, ABS_HAT0Y, -1, 1, 0, 0); in ps_gamepad_create()
530 return -EINVAL; in ps_get_report()
535 return -EINVAL; in ps_get_report()
538 if (hdev->bus == BUS_BLUETOOTH) { in ps_get_report()
540 uint8_t crc_offset = size - 4; in ps_get_report()
545 return -EILSEQ; in ps_get_report()
557 led->name = devm_kasprintf(&ps_dev->hdev->dev, GFP_KERNEL, in ps_led_register()
558 "%s:%s:%s", ps_dev->input_dev_name, led_info->color, led_info->name); in ps_led_register()
560 if (!led->name) in ps_led_register()
561 return -ENOMEM; in ps_led_register()
563 led->brightness = 0; in ps_led_register()
564 led->max_brightness = 1; in ps_led_register()
565 led->flags = LED_CORE_SUSPENDRESUME; in ps_led_register()
566 led->brightness_get = led_info->brightness_get; in ps_led_register()
567 led->brightness_set_blocking = led_info->brightness_set; in ps_led_register()
569 ret = devm_led_classdev_register(&ps_dev->hdev->dev, led); in ps_led_register()
571 hid_err(ps_dev->hdev, "Failed to register LED %s: %d\n", led_info->name, ret); in ps_led_register()
582 struct hid_device *hdev = ps_dev->hdev; in ps_lightbar_register()
587 mc_led_info = devm_kmalloc_array(&hdev->dev, 3, sizeof(*mc_led_info), in ps_lightbar_register()
590 return -ENOMEM; in ps_lightbar_register()
596 lightbar_mc_dev->subled_info = mc_led_info; in ps_lightbar_register()
597 lightbar_mc_dev->num_colors = 3; in ps_lightbar_register()
599 led_cdev = &lightbar_mc_dev->led_cdev; in ps_lightbar_register()
600 led_cdev->name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s:rgb:indicator", in ps_lightbar_register()
601 ps_dev->input_dev_name); in ps_lightbar_register()
602 if (!led_cdev->name) in ps_lightbar_register()
603 return -ENOMEM; in ps_lightbar_register()
604 led_cdev->brightness = 255; in ps_lightbar_register()
605 led_cdev->max_brightness = 255; in ps_lightbar_register()
606 led_cdev->brightness_set_blocking = brightness_set; in ps_lightbar_register()
608 ret = devm_led_classdev_multicolor_register(&hdev->dev, lightbar_mc_dev); in ps_lightbar_register()
620 struct input_dev *sensors; in ps_sensors_create() local
623 sensors = ps_allocate_input_dev(hdev, "Motion Sensors"); in ps_sensors_create()
624 if (IS_ERR(sensors)) in ps_sensors_create()
625 return ERR_CAST(sensors); in ps_sensors_create()
627 __set_bit(INPUT_PROP_ACCELEROMETER, sensors->propbit); in ps_sensors_create()
628 __set_bit(EV_MSC, sensors->evbit); in ps_sensors_create()
629 __set_bit(MSC_TIMESTAMP, sensors->mscbit); in ps_sensors_create()
632 input_set_abs_params(sensors, ABS_X, -accel_range, accel_range, 16, 0); in ps_sensors_create()
633 input_set_abs_params(sensors, ABS_Y, -accel_range, accel_range, 16, 0); in ps_sensors_create()
634 input_set_abs_params(sensors, ABS_Z, -accel_range, accel_range, 16, 0); in ps_sensors_create()
635 input_abs_set_res(sensors, ABS_X, accel_res); in ps_sensors_create()
636 input_abs_set_res(sensors, ABS_Y, accel_res); in ps_sensors_create()
637 input_abs_set_res(sensors, ABS_Z, accel_res); in ps_sensors_create()
640 input_set_abs_params(sensors, ABS_RX, -gyro_range, gyro_range, 16, 0); in ps_sensors_create()
641 input_set_abs_params(sensors, ABS_RY, -gyro_range, gyro_range, 16, 0); in ps_sensors_create()
642 input_set_abs_params(sensors, ABS_RZ, -gyro_range, gyro_range, 16, 0); in ps_sensors_create()
643 input_abs_set_res(sensors, ABS_RX, gyro_res); in ps_sensors_create()
644 input_abs_set_res(sensors, ABS_RY, gyro_res); in ps_sensors_create()
645 input_abs_set_res(sensors, ABS_RZ, gyro_res); in ps_sensors_create()
647 ret = input_register_device(sensors); in ps_sensors_create()
651 return sensors; in ps_sensors_create()
666 __set_bit(INPUT_PROP_BUTTONPAD, touchpad->propbit); in ps_touchpad_create()
668 input_set_abs_params(touchpad, ABS_MT_POSITION_X, 0, width - 1, 0, 0); in ps_touchpad_create()
669 input_set_abs_params(touchpad, ABS_MT_POSITION_Y, 0, height - 1, 0, 0); in ps_touchpad_create()
689 return sysfs_emit(buf, "0x%08x\n", ps_dev->fw_version); in firmware_version_show()
701 return sysfs_emit(buf, "0x%08x\n", ps_dev->hw_version); in hardware_version_show()
729 return -ENOMEM; in dualsense_get_calibration_data()
731 ret = ps_get_report(ds->base.hdev, DS_FEATURE_REPORT_CALIBRATION, buf, in dualsense_get_calibration_data()
734 hid_err(ds->base.hdev, "Failed to retrieve DualSense calibration info: %d\n", ret); in dualsense_get_calibration_data()
761 ds->gyro_calib_data[0].abs_code = ABS_RX; in dualsense_get_calibration_data()
762 ds->gyro_calib_data[0].bias = gyro_pitch_bias; in dualsense_get_calibration_data()
763 ds->gyro_calib_data[0].sens_numer = speed_2x*DS_GYRO_RES_PER_DEG_S; in dualsense_get_calibration_data()
764 ds->gyro_calib_data[0].sens_denom = gyro_pitch_plus - gyro_pitch_minus; in dualsense_get_calibration_data()
766 ds->gyro_calib_data[1].abs_code = ABS_RY; in dualsense_get_calibration_data()
767 ds->gyro_calib_data[1].bias = gyro_yaw_bias; in dualsense_get_calibration_data()
768 ds->gyro_calib_data[1].sens_numer = speed_2x*DS_GYRO_RES_PER_DEG_S; in dualsense_get_calibration_data()
769 ds->gyro_calib_data[1].sens_denom = gyro_yaw_plus - gyro_yaw_minus; in dualsense_get_calibration_data()
771 ds->gyro_calib_data[2].abs_code = ABS_RZ; in dualsense_get_calibration_data()
772 ds->gyro_calib_data[2].bias = gyro_roll_bias; in dualsense_get_calibration_data()
773 ds->gyro_calib_data[2].sens_numer = speed_2x*DS_GYRO_RES_PER_DEG_S; in dualsense_get_calibration_data()
774 ds->gyro_calib_data[2].sens_denom = gyro_roll_plus - gyro_roll_minus; in dualsense_get_calibration_data()
780 range_2g = acc_x_plus - acc_x_minus; in dualsense_get_calibration_data()
781 ds->accel_calib_data[0].abs_code = ABS_X; in dualsense_get_calibration_data()
782 ds->accel_calib_data[0].bias = acc_x_plus - range_2g / 2; in dualsense_get_calibration_data()
783 ds->accel_calib_data[0].sens_numer = 2*DS_ACC_RES_PER_G; in dualsense_get_calibration_data()
784 ds->accel_calib_data[0].sens_denom = range_2g; in dualsense_get_calibration_data()
786 range_2g = acc_y_plus - acc_y_minus; in dualsense_get_calibration_data()
787 ds->accel_calib_data[1].abs_code = ABS_Y; in dualsense_get_calibration_data()
788 ds->accel_calib_data[1].bias = acc_y_plus - range_2g / 2; in dualsense_get_calibration_data()
789 ds->accel_calib_data[1].sens_numer = 2*DS_ACC_RES_PER_G; in dualsense_get_calibration_data()
790 ds->accel_calib_data[1].sens_denom = range_2g; in dualsense_get_calibration_data()
792 range_2g = acc_z_plus - acc_z_minus; in dualsense_get_calibration_data()
793 ds->accel_calib_data[2].abs_code = ABS_Z; in dualsense_get_calibration_data()
794 ds->accel_calib_data[2].bias = acc_z_plus - range_2g / 2; in dualsense_get_calibration_data()
795 ds->accel_calib_data[2].sens_numer = 2*DS_ACC_RES_PER_G; in dualsense_get_calibration_data()
796 ds->accel_calib_data[2].sens_denom = range_2g; in dualsense_get_calibration_data()
811 return -ENOMEM; in dualsense_get_firmware_info()
813 ret = ps_get_report(ds->base.hdev, DS_FEATURE_REPORT_FIRMWARE_INFO, buf, in dualsense_get_firmware_info()
816 hid_err(ds->base.hdev, "Failed to retrieve DualSense firmware info: %d\n", ret); in dualsense_get_firmware_info()
820 ds->base.hw_version = get_unaligned_le32(&buf[24]); in dualsense_get_firmware_info()
821 ds->base.fw_version = get_unaligned_le32(&buf[28]); in dualsense_get_firmware_info()
830 ds->update_version = get_unaligned_le16(&buf[44]); in dualsense_get_firmware_info()
844 return -ENOMEM; in dualsense_get_mac_address()
846 ret = ps_get_report(ds->base.hdev, DS_FEATURE_REPORT_PAIRING_INFO, buf, in dualsense_get_mac_address()
849 hid_err(ds->base.hdev, "Failed to retrieve DualSense pairing info: %d\n", ret); in dualsense_get_mac_address()
853 memcpy(ds->base.mac_address, &buf[1], sizeof(ds->base.mac_address)); in dualsense_get_mac_address()
868 red = mc_cdev->subled_info[0].brightness; in dualsense_lightbar_set_brightness()
869 green = mc_cdev->subled_info[1].brightness; in dualsense_lightbar_set_brightness()
870 blue = mc_cdev->subled_info[2].brightness; in dualsense_lightbar_set_brightness()
878 struct hid_device *hdev = to_hid_device(led->dev->parent); in dualsense_player_led_get_brightness()
881 return !!(ds->player_leds_state & BIT(led - ds->player_leds)); in dualsense_player_led_get_brightness()
886 struct hid_device *hdev = to_hid_device(led->dev->parent); in dualsense_player_led_set_brightness()
891 spin_lock_irqsave(&ds->base.lock, flags); in dualsense_player_led_set_brightness()
893 led_index = led - ds->player_leds; in dualsense_player_led_set_brightness()
895 ds->player_leds_state &= ~BIT(led_index); in dualsense_player_led_set_brightness()
897 ds->player_leds_state |= BIT(led_index); in dualsense_player_led_set_brightness()
899 ds->update_player_leds = true; in dualsense_player_led_set_brightness()
900 spin_unlock_irqrestore(&ds->base.lock, flags); in dualsense_player_led_set_brightness()
910 struct hid_device *hdev = ds->base.hdev; in dualsense_init_output_report()
912 if (hdev->bus == BUS_BLUETOOTH) { in dualsense_init_output_report()
916 bt->report_id = DS_OUTPUT_REPORT_BT; in dualsense_init_output_report()
917 bt->tag = DS_OUTPUT_TAG; /* Tag must be set. Exact meaning is unclear. */ in dualsense_init_output_report()
920 * Highest 4-bit is a sequence number, which needs to be increased in dualsense_init_output_report()
921 * every report. Lowest 4-bit is tag and can be zero for now. in dualsense_init_output_report()
923 bt->seq_tag = (ds->output_seq << 4) | 0x0; in dualsense_init_output_report()
924 if (++ds->output_seq == 16) in dualsense_init_output_report()
925 ds->output_seq = 0; in dualsense_init_output_report()
927 rp->data = buf; in dualsense_init_output_report()
928 rp->len = sizeof(*bt); in dualsense_init_output_report()
929 rp->bt = bt; in dualsense_init_output_report()
930 rp->usb = NULL; in dualsense_init_output_report()
931 rp->common = &bt->common; in dualsense_init_output_report()
936 usb->report_id = DS_OUTPUT_REPORT_USB; in dualsense_init_output_report()
938 rp->data = buf; in dualsense_init_output_report()
939 rp->len = sizeof(*usb); in dualsense_init_output_report()
940 rp->bt = NULL; in dualsense_init_output_report()
941 rp->usb = usb; in dualsense_init_output_report()
942 rp->common = &usb->common; in dualsense_init_output_report()
950 spin_lock_irqsave(&ds->base.lock, flags); in dualsense_schedule_work()
951 if (ds->output_worker_initialized) in dualsense_schedule_work()
952 schedule_work(&ds->output_worker); in dualsense_schedule_work()
953 spin_unlock_irqrestore(&ds->base.lock, flags); in dualsense_schedule_work()
963 struct hid_device *hdev = ds->base.hdev; in dualsense_send_output_report()
966 if (report->bt) { in dualsense_send_output_report()
971 crc = ~crc32_le(crc, report->data, report->len - 4); in dualsense_send_output_report()
973 report->bt->crc32 = cpu_to_le32(crc); in dualsense_send_output_report()
976 hid_hw_output_report(hdev, report->data, report->len); in dualsense_send_output_report()
986 dualsense_init_output_report(ds, &report, ds->output_report_dmabuf); in dualsense_output_worker()
989 spin_lock_irqsave(&ds->base.lock, flags); in dualsense_output_worker()
991 if (ds->update_rumble) { in dualsense_output_worker()
993 common->valid_flag0 |= DS_OUTPUT_VALID_FLAG0_HAPTICS_SELECT; in dualsense_output_worker()
994 if (ds->use_vibration_v2) in dualsense_output_worker()
995 common->valid_flag2 |= DS_OUTPUT_VALID_FLAG2_COMPATIBLE_VIBRATION2; in dualsense_output_worker()
997 common->valid_flag0 |= DS_OUTPUT_VALID_FLAG0_COMPATIBLE_VIBRATION; in dualsense_output_worker()
998 common->motor_left = ds->motor_left; in dualsense_output_worker()
999 common->motor_right = ds->motor_right; in dualsense_output_worker()
1000 ds->update_rumble = false; in dualsense_output_worker()
1003 if (ds->update_lightbar) { in dualsense_output_worker()
1004 common->valid_flag1 |= DS_OUTPUT_VALID_FLAG1_LIGHTBAR_CONTROL_ENABLE; in dualsense_output_worker()
1005 common->lightbar_red = ds->lightbar_red; in dualsense_output_worker()
1006 common->lightbar_green = ds->lightbar_green; in dualsense_output_worker()
1007 common->lightbar_blue = ds->lightbar_blue; in dualsense_output_worker()
1009 ds->update_lightbar = false; in dualsense_output_worker()
1012 if (ds->update_player_leds) { in dualsense_output_worker()
1013 common->valid_flag1 |= DS_OUTPUT_VALID_FLAG1_PLAYER_INDICATOR_CONTROL_ENABLE; in dualsense_output_worker()
1014 common->player_leds = ds->player_leds_state; in dualsense_output_worker()
1016 ds->update_player_leds = false; in dualsense_output_worker()
1019 if (ds->update_mic_mute) { in dualsense_output_worker()
1020 common->valid_flag1 |= DS_OUTPUT_VALID_FLAG1_MIC_MUTE_LED_CONTROL_ENABLE; in dualsense_output_worker()
1021 common->mute_button_led = ds->mic_muted; in dualsense_output_worker()
1023 if (ds->mic_muted) { in dualsense_output_worker()
1025 common->valid_flag1 |= DS_OUTPUT_VALID_FLAG1_POWER_SAVE_CONTROL_ENABLE; in dualsense_output_worker()
1026 common->power_save_control |= DS_OUTPUT_POWER_SAVE_CONTROL_MIC_MUTE; in dualsense_output_worker()
1029 common->valid_flag1 |= DS_OUTPUT_VALID_FLAG1_POWER_SAVE_CONTROL_ENABLE; in dualsense_output_worker()
1030 common->power_save_control &= ~DS_OUTPUT_POWER_SAVE_CONTROL_MIC_MUTE; in dualsense_output_worker()
1033 ds->update_mic_mute = false; in dualsense_output_worker()
1036 spin_unlock_irqrestore(&ds->base.lock, flags); in dualsense_output_worker()
1044 struct hid_device *hdev = ps_dev->hdev; in dualsense_parse_report()
1059 if (hdev->bus == BUS_USB && report->id == DS_INPUT_REPORT_USB && in dualsense_parse_report()
1062 } else if (hdev->bus == BUS_BLUETOOTH && report->id == DS_INPUT_REPORT_BT && in dualsense_parse_report()
1065 uint32_t report_crc = get_unaligned_le32(&data[size - 4]); in dualsense_parse_report()
1067 if (!ps_check_crc32(PS_INPUT_CRC32_SEED, data, size - 4, report_crc)) { in dualsense_parse_report()
1069 return -EILSEQ; in dualsense_parse_report()
1074 hid_err(hdev, "Unhandled reportID=%d\n", report->id); in dualsense_parse_report()
1075 return -1; in dualsense_parse_report()
1078 input_report_abs(ds->gamepad, ABS_X, ds_report->x); in dualsense_parse_report()
1079 input_report_abs(ds->gamepad, ABS_Y, ds_report->y); in dualsense_parse_report()
1080 input_report_abs(ds->gamepad, ABS_RX, ds_report->rx); in dualsense_parse_report()
1081 input_report_abs(ds->gamepad, ABS_RY, ds_report->ry); in dualsense_parse_report()
1082 input_report_abs(ds->gamepad, ABS_Z, ds_report->z); in dualsense_parse_report()
1083 input_report_abs(ds->gamepad, ABS_RZ, ds_report->rz); in dualsense_parse_report()
1085 value = ds_report->buttons[0] & DS_BUTTONS0_HAT_SWITCH; in dualsense_parse_report()
1088 input_report_abs(ds->gamepad, ABS_HAT0X, ps_gamepad_hat_mapping[value].x); in dualsense_parse_report()
1089 input_report_abs(ds->gamepad, ABS_HAT0Y, ps_gamepad_hat_mapping[value].y); in dualsense_parse_report()
1091 input_report_key(ds->gamepad, BTN_WEST, ds_report->buttons[0] & DS_BUTTONS0_SQUARE); in dualsense_parse_report()
1092 input_report_key(ds->gamepad, BTN_SOUTH, ds_report->buttons[0] & DS_BUTTONS0_CROSS); in dualsense_parse_report()
1093 input_report_key(ds->gamepad, BTN_EAST, ds_report->buttons[0] & DS_BUTTONS0_CIRCLE); in dualsense_parse_report()
1094 input_report_key(ds->gamepad, BTN_NORTH, ds_report->buttons[0] & DS_BUTTONS0_TRIANGLE); in dualsense_parse_report()
1095 input_report_key(ds->gamepad, BTN_TL, ds_report->buttons[1] & DS_BUTTONS1_L1); in dualsense_parse_report()
1096 input_report_key(ds->gamepad, BTN_TR, ds_report->buttons[1] & DS_BUTTONS1_R1); in dualsense_parse_report()
1097 input_report_key(ds->gamepad, BTN_TL2, ds_report->buttons[1] & DS_BUTTONS1_L2); in dualsense_parse_report()
1098 input_report_key(ds->gamepad, BTN_TR2, ds_report->buttons[1] & DS_BUTTONS1_R2); in dualsense_parse_report()
1099 input_report_key(ds->gamepad, BTN_SELECT, ds_report->buttons[1] & DS_BUTTONS1_CREATE); in dualsense_parse_report()
1100 input_report_key(ds->gamepad, BTN_START, ds_report->buttons[1] & DS_BUTTONS1_OPTIONS); in dualsense_parse_report()
1101 input_report_key(ds->gamepad, BTN_THUMBL, ds_report->buttons[1] & DS_BUTTONS1_L3); in dualsense_parse_report()
1102 input_report_key(ds->gamepad, BTN_THUMBR, ds_report->buttons[1] & DS_BUTTONS1_R3); in dualsense_parse_report()
1103 input_report_key(ds->gamepad, BTN_MODE, ds_report->buttons[2] & DS_BUTTONS2_PS_HOME); in dualsense_parse_report()
1104 input_sync(ds->gamepad); in dualsense_parse_report()
1111 btn_mic_state = !!(ds_report->buttons[2] & DS_BUTTONS2_MIC_MUTE); in dualsense_parse_report()
1112 if (btn_mic_state && !ds->last_btn_mic_state) { in dualsense_parse_report()
1113 spin_lock_irqsave(&ps_dev->lock, flags); in dualsense_parse_report()
1114 ds->update_mic_mute = true; in dualsense_parse_report()
1115 ds->mic_muted = !ds->mic_muted; /* toggle */ in dualsense_parse_report()
1116 spin_unlock_irqrestore(&ps_dev->lock, flags); in dualsense_parse_report()
1121 ds->last_btn_mic_state = btn_mic_state; in dualsense_parse_report()
1124 for (i = 0; i < ARRAY_SIZE(ds_report->gyro); i++) { in dualsense_parse_report()
1125 int raw_data = (short)le16_to_cpu(ds_report->gyro[i]); in dualsense_parse_report()
1126 int calib_data = mult_frac(ds->gyro_calib_data[i].sens_numer, in dualsense_parse_report()
1127 raw_data - ds->gyro_calib_data[i].bias, in dualsense_parse_report()
1128 ds->gyro_calib_data[i].sens_denom); in dualsense_parse_report()
1130 input_report_abs(ds->sensors, ds->gyro_calib_data[i].abs_code, calib_data); in dualsense_parse_report()
1134 for (i = 0; i < ARRAY_SIZE(ds_report->accel); i++) { in dualsense_parse_report()
1135 int raw_data = (short)le16_to_cpu(ds_report->accel[i]); in dualsense_parse_report()
1136 int calib_data = mult_frac(ds->accel_calib_data[i].sens_numer, in dualsense_parse_report()
1137 raw_data - ds->accel_calib_data[i].bias, in dualsense_parse_report()
1138 ds->accel_calib_data[i].sens_denom); in dualsense_parse_report()
1140 input_report_abs(ds->sensors, ds->accel_calib_data[i].abs_code, calib_data); in dualsense_parse_report()
1144 sensor_timestamp = le32_to_cpu(ds_report->sensor_timestamp); in dualsense_parse_report()
1145 if (!ds->sensor_timestamp_initialized) { in dualsense_parse_report()
1146 ds->sensor_timestamp_us = DIV_ROUND_CLOSEST(sensor_timestamp, 3); in dualsense_parse_report()
1147 ds->sensor_timestamp_initialized = true; in dualsense_parse_report()
1151 if (ds->prev_sensor_timestamp > sensor_timestamp) in dualsense_parse_report()
1152 delta = (U32_MAX - ds->prev_sensor_timestamp + sensor_timestamp + 1); in dualsense_parse_report()
1154 delta = sensor_timestamp - ds->prev_sensor_timestamp; in dualsense_parse_report()
1155 ds->sensor_timestamp_us += DIV_ROUND_CLOSEST(delta, 3); in dualsense_parse_report()
1157 ds->prev_sensor_timestamp = sensor_timestamp; in dualsense_parse_report()
1158 input_event(ds->sensors, EV_MSC, MSC_TIMESTAMP, ds->sensor_timestamp_us); in dualsense_parse_report()
1159 input_sync(ds->sensors); in dualsense_parse_report()
1161 for (i = 0; i < ARRAY_SIZE(ds_report->points); i++) { in dualsense_parse_report()
1162 struct dualsense_touch_point *point = &ds_report->points[i]; in dualsense_parse_report()
1163 bool active = (point->contact & DS_TOUCH_POINT_INACTIVE) ? false : true; in dualsense_parse_report()
1165 input_mt_slot(ds->touchpad, i); in dualsense_parse_report()
1166 input_mt_report_slot_state(ds->touchpad, MT_TOOL_FINGER, active); in dualsense_parse_report()
1169 int x = (point->x_hi << 8) | point->x_lo; in dualsense_parse_report()
1170 int y = (point->y_hi << 4) | point->y_lo; in dualsense_parse_report()
1172 input_report_abs(ds->touchpad, ABS_MT_POSITION_X, x); in dualsense_parse_report()
1173 input_report_abs(ds->touchpad, ABS_MT_POSITION_Y, y); in dualsense_parse_report()
1176 input_mt_sync_frame(ds->touchpad); in dualsense_parse_report()
1177 input_report_key(ds->touchpad, BTN_LEFT, ds_report->buttons[2] & DS_BUTTONS2_TOUCHPAD); in dualsense_parse_report()
1178 input_sync(ds->touchpad); in dualsense_parse_report()
1180 battery_data = ds_report->status & DS_STATUS_BATTERY_CAPACITY; in dualsense_parse_report()
1181 charging_status = (ds_report->status & DS_STATUS_CHARGING) >> DS_STATUS_CHARGING_SHIFT; in dualsense_parse_report()
1187 * 0 = 0-9%, 1 = 10-19%, .. and 10 = 100% in dualsense_parse_report()
1211 spin_lock_irqsave(&ps_dev->lock, flags); in dualsense_parse_report()
1212 ps_dev->battery_capacity = battery_capacity; in dualsense_parse_report()
1213 ps_dev->battery_status = battery_status; in dualsense_parse_report()
1214 spin_unlock_irqrestore(&ps_dev->lock, flags); in dualsense_parse_report()
1225 if (effect->type != FF_RUMBLE) in dualsense_play_effect()
1228 spin_lock_irqsave(&ds->base.lock, flags); in dualsense_play_effect()
1229 ds->update_rumble = true; in dualsense_play_effect()
1230 ds->motor_left = effect->u.rumble.strong_magnitude / 256; in dualsense_play_effect()
1231 ds->motor_right = effect->u.rumble.weak_magnitude / 256; in dualsense_play_effect()
1232 spin_unlock_irqrestore(&ds->base.lock, flags); in dualsense_play_effect()
1243 spin_lock_irqsave(&ds->base.lock, flags); in dualsense_remove()
1244 ds->output_worker_initialized = false; in dualsense_remove()
1245 spin_unlock_irqrestore(&ds->base.lock, flags); in dualsense_remove()
1247 cancel_work_sync(&ds->output_worker); in dualsense_remove()
1257 return -ENOMEM; in dualsense_reset_leds()
1267 report.common->valid_flag2 = DS_OUTPUT_VALID_FLAG2_LIGHTBAR_SETUP_CONTROL_ENABLE; in dualsense_reset_leds()
1268 report.common->lightbar_setup = DS_OUTPUT_LIGHTBAR_SETUP_LIGHT_OUT; /* Fade light out. */ in dualsense_reset_leds()
1279 spin_lock_irqsave(&ds->base.lock, flags); in dualsense_set_lightbar()
1280 ds->update_lightbar = true; in dualsense_set_lightbar()
1281 ds->lightbar_red = red; in dualsense_set_lightbar()
1282 ds->lightbar_green = green; in dualsense_set_lightbar()
1283 ds->lightbar_blue = blue; in dualsense_set_lightbar()
1284 spin_unlock_irqrestore(&ds->base.lock, flags); in dualsense_set_lightbar()
1294 * across the LEDs, so e.g. player 1 would be "--x--" with x being 'on'. in dualsense_set_player_leds()
1305 uint8_t player_id = ds->base.player_id % ARRAY_SIZE(player_ids); in dualsense_set_player_leds()
1307 ds->update_player_leds = true; in dualsense_set_player_leds()
1308 ds->player_leds_state = player_ids[player_id]; in dualsense_set_player_leds()
1332 ds = devm_kzalloc(&hdev->dev, sizeof(*ds), GFP_KERNEL); in dualsense_create()
1334 return ERR_PTR(-ENOMEM); in dualsense_create()
1338 * hid-generic vs hid-playstation axis and button mapping. in dualsense_create()
1340 hdev->version |= HID_PLAYSTATION_VERSION_PATCH; in dualsense_create()
1342 ps_dev = &ds->base; in dualsense_create()
1343 ps_dev->hdev = hdev; in dualsense_create()
1344 spin_lock_init(&ps_dev->lock); in dualsense_create()
1345 ps_dev->battery_capacity = 100; /* initial value until parse_report. */ in dualsense_create()
1346 ps_dev->battery_status = POWER_SUPPLY_STATUS_UNKNOWN; in dualsense_create()
1347 ps_dev->parse_report = dualsense_parse_report; in dualsense_create()
1348 ps_dev->remove = dualsense_remove; in dualsense_create()
1349 INIT_WORK(&ds->output_worker, dualsense_output_worker); in dualsense_create()
1350 ds->output_worker_initialized = true; in dualsense_create()
1354 ds->output_report_dmabuf = devm_kzalloc(&hdev->dev, max_output_report_size, GFP_KERNEL); in dualsense_create()
1355 if (!ds->output_report_dmabuf) in dualsense_create()
1356 return ERR_PTR(-ENOMEM); in dualsense_create()
1363 snprintf(hdev->uniq, sizeof(hdev->uniq), "%pMR", ds->base.mac_address); in dualsense_create()
1379 if (hdev->product == USB_DEVICE_ID_SONY_PS5_CONTROLLER) { in dualsense_create()
1381 ds->use_vibration_v2 = ds->update_version >= DS_FEATURE_VERSION(2, 21); in dualsense_create()
1382 } else if (hdev->product == USB_DEVICE_ID_SONY_PS5_CONTROLLER_2) { in dualsense_create()
1383 ds->use_vibration_v2 = true; in dualsense_create()
1396 ds->gamepad = ps_gamepad_create(hdev, dualsense_play_effect); in dualsense_create()
1397 if (IS_ERR(ds->gamepad)) { in dualsense_create()
1398 ret = PTR_ERR(ds->gamepad); in dualsense_create()
1402 ps_dev->input_dev_name = dev_name(&ds->gamepad->dev); in dualsense_create()
1404 ds->sensors = ps_sensors_create(hdev, DS_ACC_RANGE, DS_ACC_RES_PER_G, in dualsense_create()
1406 if (IS_ERR(ds->sensors)) { in dualsense_create()
1407 ret = PTR_ERR(ds->sensors); in dualsense_create()
1411 ds->touchpad = ps_touchpad_create(hdev, DS_TOUCHPAD_WIDTH, DS_TOUCHPAD_HEIGHT, 2); in dualsense_create()
1412 if (IS_ERR(ds->touchpad)) { in dualsense_create()
1413 ret = PTR_ERR(ds->touchpad); in dualsense_create()
1430 ret = ps_lightbar_register(ps_dev, &ds->lightbar, dualsense_lightbar_set_brightness); in dualsense_create()
1440 ret = ps_led_register(ps_dev, &ds->player_leds[i], led_info); in dualsense_create()
1459 ds->base.hw_version, ds->base.fw_version); in dualsense_create()
1461 return &ds->base; in dualsense_create()
1473 if (dev && dev->parse_report) in ps_raw_event()
1474 return dev->parse_report(dev, report, data, size); in ps_raw_event()
1502 if (hdev->product == USB_DEVICE_ID_SONY_PS5_CONTROLLER || in ps_probe()
1503 hdev->product == USB_DEVICE_ID_SONY_PS5_CONTROLLER_2) { in ps_probe()
1528 if (dev->remove) in ps_remove()
1529 dev->remove(dev); in ps_remove()