Lines Matching +full:motion +full:- +full:sensors

1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright (c) 2020-2022 Sony Interactive Entertainment
15 #include <linux/led-class-multicolor.h>
20 #include "hid-ids.h"
57 /* Calibration data for playstation motion sensors. */
154 struct input_dev *sensors; member
215 /* Motion sensors */
229 static_assert(sizeof(struct dualsense_input_report) == DS_INPUT_REPORT_USB_SIZE - 1);
333 * 0x00 - 1ms
334 * 0x01 - 1ms
335 * 0x02 - 2ms
336 * 0x3E - 62ms
337 * 0x3F - disabled
369 struct input_dev *sensors; member
431 /* Motion sensors */
536 {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1},
557 if (!memcmp(entry->mac_address, dev->mac_address, sizeof(dev->mac_address))) { in ps_devices_list_add()
558 hid_err(dev->hdev, "Duplicate device found for MAC address %pMR.\n", in ps_devices_list_add()
559 dev->mac_address); in ps_devices_list_add()
561 return -EEXIST; in ps_devices_list_add()
565 list_add_tail(&dev->list, &ps_devices_list); in ps_devices_list_add()
573 list_del(&dev->list); in ps_devices_list_remove()
585 dev->player_id = ret; in ps_device_set_player_id()
591 ida_free(&ps_player_id_allocator, dev->player_id); in ps_device_release_player_id()
593 dev->player_id = U32_MAX; in ps_device_release_player_id()
600 input_dev = devm_input_allocate_device(&hdev->dev); in ps_allocate_input_dev()
602 return ERR_PTR(-ENOMEM); in ps_allocate_input_dev()
604 input_dev->id.bustype = hdev->bus; in ps_allocate_input_dev()
605 input_dev->id.vendor = hdev->vendor; in ps_allocate_input_dev()
606 input_dev->id.product = hdev->product; in ps_allocate_input_dev()
607 input_dev->id.version = hdev->version; in ps_allocate_input_dev()
608 input_dev->uniq = hdev->uniq; in ps_allocate_input_dev()
611 input_dev->name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s %s", hdev->name, in ps_allocate_input_dev()
613 if (!input_dev->name) in ps_allocate_input_dev()
614 return ERR_PTR(-ENOMEM); in ps_allocate_input_dev()
616 input_dev->name = hdev->name; in ps_allocate_input_dev()
641 spin_lock_irqsave(&dev->lock, flags); in ps_battery_get_property()
642 battery_capacity = dev->battery_capacity; in ps_battery_get_property()
643 battery_status = dev->battery_status; in ps_battery_get_property()
644 spin_unlock_irqrestore(&dev->lock, flags); in ps_battery_get_property()
648 val->intval = battery_status; in ps_battery_get_property()
651 val->intval = 1; in ps_battery_get_property()
654 val->intval = battery_capacity; in ps_battery_get_property()
657 val->intval = POWER_SUPPLY_SCOPE_DEVICE; in ps_battery_get_property()
660 ret = -EINVAL; in ps_battery_get_property()
673 dev->battery_desc.type = POWER_SUPPLY_TYPE_BATTERY; in ps_device_register_battery()
674 dev->battery_desc.properties = ps_power_supply_props; in ps_device_register_battery()
675 dev->battery_desc.num_properties = ARRAY_SIZE(ps_power_supply_props); in ps_device_register_battery()
676 dev->battery_desc.get_property = ps_battery_get_property; in ps_device_register_battery()
677 dev->battery_desc.name = devm_kasprintf(&dev->hdev->dev, GFP_KERNEL, in ps_device_register_battery()
678 "ps-controller-battery-%pMR", dev->mac_address); in ps_device_register_battery()
679 if (!dev->battery_desc.name) in ps_device_register_battery()
680 return -ENOMEM; in ps_device_register_battery()
682 battery = devm_power_supply_register(&dev->hdev->dev, &dev->battery_desc, &battery_cfg); in ps_device_register_battery()
685 hid_err(dev->hdev, "Unable to register battery device: %d\n", ret); in ps_device_register_battery()
688 dev->battery = battery; in ps_device_register_battery()
690 ret = power_supply_powers(dev->battery, &dev->hdev->dev); in ps_device_register_battery()
692 hid_err(dev->hdev, "Unable to activate battery device: %d\n", ret); in ps_device_register_battery()
728 input_set_abs_params(gamepad, ABS_HAT0X, -1, 1, 0, 0); in ps_gamepad_create()
729 input_set_abs_params(gamepad, ABS_HAT0Y, -1, 1, 0, 0); in ps_gamepad_create()
762 return -EINVAL; in ps_get_report()
767 return -EINVAL; in ps_get_report()
770 if (hdev->bus == BUS_BLUETOOTH && check_crc) { in ps_get_report()
772 uint8_t crc_offset = size - 4; in ps_get_report()
777 return -EILSEQ; in ps_get_report()
789 if (led_info->name) { in ps_led_register()
790 led->name = devm_kasprintf(&ps_dev->hdev->dev, GFP_KERNEL, in ps_led_register()
791 "%s:%s:%s", ps_dev->input_dev_name, led_info->color, led_info->name); in ps_led_register()
793 /* Backwards compatible mode for hid-sony, but not compliant with LED class spec. */ in ps_led_register()
794 led->name = devm_kasprintf(&ps_dev->hdev->dev, GFP_KERNEL, in ps_led_register()
795 "%s:%s", ps_dev->input_dev_name, led_info->color); in ps_led_register()
798 if (!led->name) in ps_led_register()
799 return -ENOMEM; in ps_led_register()
801 led->brightness = 0; in ps_led_register()
802 led->max_brightness = led_info->max_brightness; in ps_led_register()
803 led->flags = LED_CORE_SUSPENDRESUME; in ps_led_register()
804 led->brightness_get = led_info->brightness_get; in ps_led_register()
805 led->brightness_set_blocking = led_info->brightness_set; in ps_led_register()
806 led->blink_set = led_info->blink_set; in ps_led_register()
808 ret = devm_led_classdev_register(&ps_dev->hdev->dev, led); in ps_led_register()
810 hid_err(ps_dev->hdev, "Failed to register LED %s: %d\n", led_info->name, ret); in ps_led_register()
821 struct hid_device *hdev = ps_dev->hdev; in ps_lightbar_register()
826 mc_led_info = devm_kmalloc_array(&hdev->dev, 3, sizeof(*mc_led_info), in ps_lightbar_register()
829 return -ENOMEM; in ps_lightbar_register()
835 lightbar_mc_dev->subled_info = mc_led_info; in ps_lightbar_register()
836 lightbar_mc_dev->num_colors = 3; in ps_lightbar_register()
838 led_cdev = &lightbar_mc_dev->led_cdev; in ps_lightbar_register()
839 led_cdev->name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s:rgb:indicator", in ps_lightbar_register()
840 ps_dev->input_dev_name); in ps_lightbar_register()
841 if (!led_cdev->name) in ps_lightbar_register()
842 return -ENOMEM; in ps_lightbar_register()
843 led_cdev->brightness = 255; in ps_lightbar_register()
844 led_cdev->max_brightness = 255; in ps_lightbar_register()
845 led_cdev->brightness_set_blocking = brightness_set; in ps_lightbar_register()
847 ret = devm_led_classdev_multicolor_register(&hdev->dev, lightbar_mc_dev); in ps_lightbar_register()
859 struct input_dev *sensors; in ps_sensors_create() local
862 sensors = ps_allocate_input_dev(hdev, "Motion Sensors"); in ps_sensors_create()
863 if (IS_ERR(sensors)) in ps_sensors_create()
864 return ERR_CAST(sensors); in ps_sensors_create()
866 __set_bit(INPUT_PROP_ACCELEROMETER, sensors->propbit); in ps_sensors_create()
867 __set_bit(EV_MSC, sensors->evbit); in ps_sensors_create()
868 __set_bit(MSC_TIMESTAMP, sensors->mscbit); in ps_sensors_create()
871 input_set_abs_params(sensors, ABS_X, -accel_range, accel_range, 16, 0); in ps_sensors_create()
872 input_set_abs_params(sensors, ABS_Y, -accel_range, accel_range, 16, 0); in ps_sensors_create()
873 input_set_abs_params(sensors, ABS_Z, -accel_range, accel_range, 16, 0); in ps_sensors_create()
874 input_abs_set_res(sensors, ABS_X, accel_res); in ps_sensors_create()
875 input_abs_set_res(sensors, ABS_Y, accel_res); in ps_sensors_create()
876 input_abs_set_res(sensors, ABS_Z, accel_res); in ps_sensors_create()
879 input_set_abs_params(sensors, ABS_RX, -gyro_range, gyro_range, 16, 0); in ps_sensors_create()
880 input_set_abs_params(sensors, ABS_RY, -gyro_range, gyro_range, 16, 0); in ps_sensors_create()
881 input_set_abs_params(sensors, ABS_RZ, -gyro_range, gyro_range, 16, 0); in ps_sensors_create()
882 input_abs_set_res(sensors, ABS_RX, gyro_res); in ps_sensors_create()
883 input_abs_set_res(sensors, ABS_RY, gyro_res); in ps_sensors_create()
884 input_abs_set_res(sensors, ABS_RZ, gyro_res); in ps_sensors_create()
886 ret = input_register_device(sensors); in ps_sensors_create()
890 return sensors; in ps_sensors_create()
905 __set_bit(INPUT_PROP_BUTTONPAD, touchpad->propbit); in ps_touchpad_create()
907 input_set_abs_params(touchpad, ABS_MT_POSITION_X, 0, width - 1, 0, 0); in ps_touchpad_create()
908 input_set_abs_params(touchpad, ABS_MT_POSITION_Y, 0, height - 1, 0, 0); in ps_touchpad_create()
928 return sysfs_emit(buf, "0x%08x\n", ps_dev->fw_version); in firmware_version_show()
940 return sysfs_emit(buf, "0x%08x\n", ps_dev->hw_version); in hardware_version_show()
954 struct hid_device *hdev = ds->base.hdev; in dualsense_get_calibration_data()
970 return -ENOMEM; in dualsense_get_calibration_data()
972 ret = ps_get_report(ds->base.hdev, DS_FEATURE_REPORT_CALIBRATION, buf, in dualsense_get_calibration_data()
975 hid_err(ds->base.hdev, "Failed to retrieve DualSense calibration info: %d\n", ret); in dualsense_get_calibration_data()
1002 ds->gyro_calib_data[0].abs_code = ABS_RX; in dualsense_get_calibration_data()
1003 ds->gyro_calib_data[0].bias = 0; in dualsense_get_calibration_data()
1004 ds->gyro_calib_data[0].sens_numer = speed_2x*DS_GYRO_RES_PER_DEG_S; in dualsense_get_calibration_data()
1005 ds->gyro_calib_data[0].sens_denom = abs(gyro_pitch_plus - gyro_pitch_bias) + in dualsense_get_calibration_data()
1006 abs(gyro_pitch_minus - gyro_pitch_bias); in dualsense_get_calibration_data()
1008 ds->gyro_calib_data[1].abs_code = ABS_RY; in dualsense_get_calibration_data()
1009 ds->gyro_calib_data[1].bias = 0; in dualsense_get_calibration_data()
1010 ds->gyro_calib_data[1].sens_numer = speed_2x*DS_GYRO_RES_PER_DEG_S; in dualsense_get_calibration_data()
1011 ds->gyro_calib_data[1].sens_denom = abs(gyro_yaw_plus - gyro_yaw_bias) + in dualsense_get_calibration_data()
1012 abs(gyro_yaw_minus - gyro_yaw_bias); in dualsense_get_calibration_data()
1014 ds->gyro_calib_data[2].abs_code = ABS_RZ; in dualsense_get_calibration_data()
1015 ds->gyro_calib_data[2].bias = 0; in dualsense_get_calibration_data()
1016 ds->gyro_calib_data[2].sens_numer = speed_2x*DS_GYRO_RES_PER_DEG_S; in dualsense_get_calibration_data()
1017 ds->gyro_calib_data[2].sens_denom = abs(gyro_roll_plus - gyro_roll_bias) + in dualsense_get_calibration_data()
1018 abs(gyro_roll_minus - gyro_roll_bias); in dualsense_get_calibration_data()
1025 for (i = 0; i < ARRAY_SIZE(ds->gyro_calib_data); i++) { in dualsense_get_calibration_data()
1026 if (ds->gyro_calib_data[i].sens_denom == 0) { in dualsense_get_calibration_data()
1028 ds->gyro_calib_data[i].abs_code); in dualsense_get_calibration_data()
1029 ds->gyro_calib_data[i].bias = 0; in dualsense_get_calibration_data()
1030 ds->gyro_calib_data[i].sens_numer = DS_GYRO_RANGE; in dualsense_get_calibration_data()
1031 ds->gyro_calib_data[i].sens_denom = S16_MAX; in dualsense_get_calibration_data()
1039 range_2g = acc_x_plus - acc_x_minus; in dualsense_get_calibration_data()
1040 ds->accel_calib_data[0].abs_code = ABS_X; in dualsense_get_calibration_data()
1041 ds->accel_calib_data[0].bias = acc_x_plus - range_2g / 2; in dualsense_get_calibration_data()
1042 ds->accel_calib_data[0].sens_numer = 2*DS_ACC_RES_PER_G; in dualsense_get_calibration_data()
1043 ds->accel_calib_data[0].sens_denom = range_2g; in dualsense_get_calibration_data()
1045 range_2g = acc_y_plus - acc_y_minus; in dualsense_get_calibration_data()
1046 ds->accel_calib_data[1].abs_code = ABS_Y; in dualsense_get_calibration_data()
1047 ds->accel_calib_data[1].bias = acc_y_plus - range_2g / 2; in dualsense_get_calibration_data()
1048 ds->accel_calib_data[1].sens_numer = 2*DS_ACC_RES_PER_G; in dualsense_get_calibration_data()
1049 ds->accel_calib_data[1].sens_denom = range_2g; in dualsense_get_calibration_data()
1051 range_2g = acc_z_plus - acc_z_minus; in dualsense_get_calibration_data()
1052 ds->accel_calib_data[2].abs_code = ABS_Z; in dualsense_get_calibration_data()
1053 ds->accel_calib_data[2].bias = acc_z_plus - range_2g / 2; in dualsense_get_calibration_data()
1054 ds->accel_calib_data[2].sens_numer = 2*DS_ACC_RES_PER_G; in dualsense_get_calibration_data()
1055 ds->accel_calib_data[2].sens_denom = range_2g; in dualsense_get_calibration_data()
1062 for (i = 0; i < ARRAY_SIZE(ds->accel_calib_data); i++) { in dualsense_get_calibration_data()
1063 if (ds->accel_calib_data[i].sens_denom == 0) { in dualsense_get_calibration_data()
1065 ds->accel_calib_data[i].abs_code); in dualsense_get_calibration_data()
1066 ds->accel_calib_data[i].bias = 0; in dualsense_get_calibration_data()
1067 ds->accel_calib_data[i].sens_numer = DS_ACC_RANGE; in dualsense_get_calibration_data()
1068 ds->accel_calib_data[i].sens_denom = S16_MAX; in dualsense_get_calibration_data()
1085 return -ENOMEM; in dualsense_get_firmware_info()
1087 ret = ps_get_report(ds->base.hdev, DS_FEATURE_REPORT_FIRMWARE_INFO, buf, in dualsense_get_firmware_info()
1090 hid_err(ds->base.hdev, "Failed to retrieve DualSense firmware info: %d\n", ret); in dualsense_get_firmware_info()
1094 ds->base.hw_version = get_unaligned_le32(&buf[24]); in dualsense_get_firmware_info()
1095 ds->base.fw_version = get_unaligned_le32(&buf[28]); in dualsense_get_firmware_info()
1104 ds->update_version = get_unaligned_le16(&buf[44]); in dualsense_get_firmware_info()
1118 return -ENOMEM; in dualsense_get_mac_address()
1120 ret = ps_get_report(ds->base.hdev, DS_FEATURE_REPORT_PAIRING_INFO, buf, in dualsense_get_mac_address()
1123 hid_err(ds->base.hdev, "Failed to retrieve DualSense pairing info: %d\n", ret); in dualsense_get_mac_address()
1127 memcpy(ds->base.mac_address, &buf[1], sizeof(ds->base.mac_address)); in dualsense_get_mac_address()
1142 red = mc_cdev->subled_info[0].brightness; in dualsense_lightbar_set_brightness()
1143 green = mc_cdev->subled_info[1].brightness; in dualsense_lightbar_set_brightness()
1144 blue = mc_cdev->subled_info[2].brightness; in dualsense_lightbar_set_brightness()
1152 struct hid_device *hdev = to_hid_device(led->dev->parent); in dualsense_player_led_get_brightness()
1155 return !!(ds->player_leds_state & BIT(led - ds->player_leds)); in dualsense_player_led_get_brightness()
1160 struct hid_device *hdev = to_hid_device(led->dev->parent); in dualsense_player_led_set_brightness()
1165 spin_lock_irqsave(&ds->base.lock, flags); in dualsense_player_led_set_brightness()
1167 led_index = led - ds->player_leds; in dualsense_player_led_set_brightness()
1169 ds->player_leds_state &= ~BIT(led_index); in dualsense_player_led_set_brightness()
1171 ds->player_leds_state |= BIT(led_index); in dualsense_player_led_set_brightness()
1173 ds->update_player_leds = true; in dualsense_player_led_set_brightness()
1174 spin_unlock_irqrestore(&ds->base.lock, flags); in dualsense_player_led_set_brightness()
1184 struct hid_device *hdev = ds->base.hdev; in dualsense_init_output_report()
1186 if (hdev->bus == BUS_BLUETOOTH) { in dualsense_init_output_report()
1190 bt->report_id = DS_OUTPUT_REPORT_BT; in dualsense_init_output_report()
1191 bt->tag = DS_OUTPUT_TAG; /* Tag must be set. Exact meaning is unclear. */ in dualsense_init_output_report()
1194 * Highest 4-bit is a sequence number, which needs to be increased in dualsense_init_output_report()
1195 * every report. Lowest 4-bit is tag and can be zero for now. in dualsense_init_output_report()
1197 bt->seq_tag = (ds->output_seq << 4) | 0x0; in dualsense_init_output_report()
1198 if (++ds->output_seq == 16) in dualsense_init_output_report()
1199 ds->output_seq = 0; in dualsense_init_output_report()
1201 rp->data = buf; in dualsense_init_output_report()
1202 rp->len = sizeof(*bt); in dualsense_init_output_report()
1203 rp->bt = bt; in dualsense_init_output_report()
1204 rp->usb = NULL; in dualsense_init_output_report()
1205 rp->common = &bt->common; in dualsense_init_output_report()
1210 usb->report_id = DS_OUTPUT_REPORT_USB; in dualsense_init_output_report()
1212 rp->data = buf; in dualsense_init_output_report()
1213 rp->len = sizeof(*usb); in dualsense_init_output_report()
1214 rp->bt = NULL; in dualsense_init_output_report()
1215 rp->usb = usb; in dualsense_init_output_report()
1216 rp->common = &usb->common; in dualsense_init_output_report()
1224 spin_lock_irqsave(&ds->base.lock, flags); in dualsense_schedule_work()
1225 if (ds->output_worker_initialized) in dualsense_schedule_work()
1226 schedule_work(&ds->output_worker); in dualsense_schedule_work()
1227 spin_unlock_irqrestore(&ds->base.lock, flags); in dualsense_schedule_work()
1237 struct hid_device *hdev = ds->base.hdev; in dualsense_send_output_report()
1240 if (report->bt) { in dualsense_send_output_report()
1245 crc = ~crc32_le(crc, report->data, report->len - 4); in dualsense_send_output_report()
1247 report->bt->crc32 = cpu_to_le32(crc); in dualsense_send_output_report()
1250 hid_hw_output_report(hdev, report->data, report->len); in dualsense_send_output_report()
1260 dualsense_init_output_report(ds, &report, ds->output_report_dmabuf); in dualsense_output_worker()
1263 spin_lock_irqsave(&ds->base.lock, flags); in dualsense_output_worker()
1265 if (ds->update_rumble) { in dualsense_output_worker()
1267 common->valid_flag0 |= DS_OUTPUT_VALID_FLAG0_HAPTICS_SELECT; in dualsense_output_worker()
1268 if (ds->use_vibration_v2) in dualsense_output_worker()
1269 common->valid_flag2 |= DS_OUTPUT_VALID_FLAG2_COMPATIBLE_VIBRATION2; in dualsense_output_worker()
1271 common->valid_flag0 |= DS_OUTPUT_VALID_FLAG0_COMPATIBLE_VIBRATION; in dualsense_output_worker()
1272 common->motor_left = ds->motor_left; in dualsense_output_worker()
1273 common->motor_right = ds->motor_right; in dualsense_output_worker()
1274 ds->update_rumble = false; in dualsense_output_worker()
1277 if (ds->update_lightbar) { in dualsense_output_worker()
1278 common->valid_flag1 |= DS_OUTPUT_VALID_FLAG1_LIGHTBAR_CONTROL_ENABLE; in dualsense_output_worker()
1279 common->lightbar_red = ds->lightbar_red; in dualsense_output_worker()
1280 common->lightbar_green = ds->lightbar_green; in dualsense_output_worker()
1281 common->lightbar_blue = ds->lightbar_blue; in dualsense_output_worker()
1283 ds->update_lightbar = false; in dualsense_output_worker()
1286 if (ds->update_player_leds) { in dualsense_output_worker()
1287 common->valid_flag1 |= DS_OUTPUT_VALID_FLAG1_PLAYER_INDICATOR_CONTROL_ENABLE; in dualsense_output_worker()
1288 common->player_leds = ds->player_leds_state; in dualsense_output_worker()
1290 ds->update_player_leds = false; in dualsense_output_worker()
1293 if (ds->update_mic_mute) { in dualsense_output_worker()
1294 common->valid_flag1 |= DS_OUTPUT_VALID_FLAG1_MIC_MUTE_LED_CONTROL_ENABLE; in dualsense_output_worker()
1295 common->mute_button_led = ds->mic_muted; in dualsense_output_worker()
1297 if (ds->mic_muted) { in dualsense_output_worker()
1299 common->valid_flag1 |= DS_OUTPUT_VALID_FLAG1_POWER_SAVE_CONTROL_ENABLE; in dualsense_output_worker()
1300 common->power_save_control |= DS_OUTPUT_POWER_SAVE_CONTROL_MIC_MUTE; in dualsense_output_worker()
1303 common->valid_flag1 |= DS_OUTPUT_VALID_FLAG1_POWER_SAVE_CONTROL_ENABLE; in dualsense_output_worker()
1304 common->power_save_control &= ~DS_OUTPUT_POWER_SAVE_CONTROL_MIC_MUTE; in dualsense_output_worker()
1307 ds->update_mic_mute = false; in dualsense_output_worker()
1310 spin_unlock_irqrestore(&ds->base.lock, flags); in dualsense_output_worker()
1318 struct hid_device *hdev = ps_dev->hdev; in dualsense_parse_report()
1333 if (hdev->bus == BUS_USB && report->id == DS_INPUT_REPORT_USB && in dualsense_parse_report()
1336 } else if (hdev->bus == BUS_BLUETOOTH && report->id == DS_INPUT_REPORT_BT && in dualsense_parse_report()
1339 uint32_t report_crc = get_unaligned_le32(&data[size - 4]); in dualsense_parse_report()
1341 if (!ps_check_crc32(PS_INPUT_CRC32_SEED, data, size - 4, report_crc)) { in dualsense_parse_report()
1343 return -EILSEQ; in dualsense_parse_report()
1348 hid_err(hdev, "Unhandled reportID=%d\n", report->id); in dualsense_parse_report()
1349 return -1; in dualsense_parse_report()
1352 input_report_abs(ds->gamepad, ABS_X, ds_report->x); in dualsense_parse_report()
1353 input_report_abs(ds->gamepad, ABS_Y, ds_report->y); in dualsense_parse_report()
1354 input_report_abs(ds->gamepad, ABS_RX, ds_report->rx); in dualsense_parse_report()
1355 input_report_abs(ds->gamepad, ABS_RY, ds_report->ry); in dualsense_parse_report()
1356 input_report_abs(ds->gamepad, ABS_Z, ds_report->z); in dualsense_parse_report()
1357 input_report_abs(ds->gamepad, ABS_RZ, ds_report->rz); in dualsense_parse_report()
1359 value = ds_report->buttons[0] & DS_BUTTONS0_HAT_SWITCH; in dualsense_parse_report()
1362 input_report_abs(ds->gamepad, ABS_HAT0X, ps_gamepad_hat_mapping[value].x); in dualsense_parse_report()
1363 input_report_abs(ds->gamepad, ABS_HAT0Y, ps_gamepad_hat_mapping[value].y); in dualsense_parse_report()
1365 input_report_key(ds->gamepad, BTN_WEST, ds_report->buttons[0] & DS_BUTTONS0_SQUARE); in dualsense_parse_report()
1366 input_report_key(ds->gamepad, BTN_SOUTH, ds_report->buttons[0] & DS_BUTTONS0_CROSS); in dualsense_parse_report()
1367 input_report_key(ds->gamepad, BTN_EAST, ds_report->buttons[0] & DS_BUTTONS0_CIRCLE); in dualsense_parse_report()
1368 input_report_key(ds->gamepad, BTN_NORTH, ds_report->buttons[0] & DS_BUTTONS0_TRIANGLE); in dualsense_parse_report()
1369 input_report_key(ds->gamepad, BTN_TL, ds_report->buttons[1] & DS_BUTTONS1_L1); in dualsense_parse_report()
1370 input_report_key(ds->gamepad, BTN_TR, ds_report->buttons[1] & DS_BUTTONS1_R1); in dualsense_parse_report()
1371 input_report_key(ds->gamepad, BTN_TL2, ds_report->buttons[1] & DS_BUTTONS1_L2); in dualsense_parse_report()
1372 input_report_key(ds->gamepad, BTN_TR2, ds_report->buttons[1] & DS_BUTTONS1_R2); in dualsense_parse_report()
1373 input_report_key(ds->gamepad, BTN_SELECT, ds_report->buttons[1] & DS_BUTTONS1_CREATE); in dualsense_parse_report()
1374 input_report_key(ds->gamepad, BTN_START, ds_report->buttons[1] & DS_BUTTONS1_OPTIONS); in dualsense_parse_report()
1375 input_report_key(ds->gamepad, BTN_THUMBL, ds_report->buttons[1] & DS_BUTTONS1_L3); in dualsense_parse_report()
1376 input_report_key(ds->gamepad, BTN_THUMBR, ds_report->buttons[1] & DS_BUTTONS1_R3); in dualsense_parse_report()
1377 input_report_key(ds->gamepad, BTN_MODE, ds_report->buttons[2] & DS_BUTTONS2_PS_HOME); in dualsense_parse_report()
1378 input_sync(ds->gamepad); in dualsense_parse_report()
1385 btn_mic_state = !!(ds_report->buttons[2] & DS_BUTTONS2_MIC_MUTE); in dualsense_parse_report()
1386 if (btn_mic_state && !ds->last_btn_mic_state) { in dualsense_parse_report()
1387 spin_lock_irqsave(&ps_dev->lock, flags); in dualsense_parse_report()
1388 ds->update_mic_mute = true; in dualsense_parse_report()
1389 ds->mic_muted = !ds->mic_muted; /* toggle */ in dualsense_parse_report()
1390 spin_unlock_irqrestore(&ps_dev->lock, flags); in dualsense_parse_report()
1395 ds->last_btn_mic_state = btn_mic_state; in dualsense_parse_report()
1398 for (i = 0; i < ARRAY_SIZE(ds_report->gyro); i++) { in dualsense_parse_report()
1399 int raw_data = (short)le16_to_cpu(ds_report->gyro[i]); in dualsense_parse_report()
1400 int calib_data = mult_frac(ds->gyro_calib_data[i].sens_numer, in dualsense_parse_report()
1401 raw_data, ds->gyro_calib_data[i].sens_denom); in dualsense_parse_report()
1403 input_report_abs(ds->sensors, ds->gyro_calib_data[i].abs_code, calib_data); in dualsense_parse_report()
1407 for (i = 0; i < ARRAY_SIZE(ds_report->accel); i++) { in dualsense_parse_report()
1408 int raw_data = (short)le16_to_cpu(ds_report->accel[i]); in dualsense_parse_report()
1409 int calib_data = mult_frac(ds->accel_calib_data[i].sens_numer, in dualsense_parse_report()
1410 raw_data - ds->accel_calib_data[i].bias, in dualsense_parse_report()
1411 ds->accel_calib_data[i].sens_denom); in dualsense_parse_report()
1413 input_report_abs(ds->sensors, ds->accel_calib_data[i].abs_code, calib_data); in dualsense_parse_report()
1417 sensor_timestamp = le32_to_cpu(ds_report->sensor_timestamp); in dualsense_parse_report()
1418 if (!ds->sensor_timestamp_initialized) { in dualsense_parse_report()
1419 ds->sensor_timestamp_us = DIV_ROUND_CLOSEST(sensor_timestamp, 3); in dualsense_parse_report()
1420 ds->sensor_timestamp_initialized = true; in dualsense_parse_report()
1424 if (ds->prev_sensor_timestamp > sensor_timestamp) in dualsense_parse_report()
1425 delta = (U32_MAX - ds->prev_sensor_timestamp + sensor_timestamp + 1); in dualsense_parse_report()
1427 delta = sensor_timestamp - ds->prev_sensor_timestamp; in dualsense_parse_report()
1428 ds->sensor_timestamp_us += DIV_ROUND_CLOSEST(delta, 3); in dualsense_parse_report()
1430 ds->prev_sensor_timestamp = sensor_timestamp; in dualsense_parse_report()
1431 input_event(ds->sensors, EV_MSC, MSC_TIMESTAMP, ds->sensor_timestamp_us); in dualsense_parse_report()
1432 input_sync(ds->sensors); in dualsense_parse_report()
1434 for (i = 0; i < ARRAY_SIZE(ds_report->points); i++) { in dualsense_parse_report()
1435 struct dualsense_touch_point *point = &ds_report->points[i]; in dualsense_parse_report()
1436 bool active = (point->contact & DS_TOUCH_POINT_INACTIVE) ? false : true; in dualsense_parse_report()
1438 input_mt_slot(ds->touchpad, i); in dualsense_parse_report()
1439 input_mt_report_slot_state(ds->touchpad, MT_TOOL_FINGER, active); in dualsense_parse_report()
1442 int x = (point->x_hi << 8) | point->x_lo; in dualsense_parse_report()
1443 int y = (point->y_hi << 4) | point->y_lo; in dualsense_parse_report()
1445 input_report_abs(ds->touchpad, ABS_MT_POSITION_X, x); in dualsense_parse_report()
1446 input_report_abs(ds->touchpad, ABS_MT_POSITION_Y, y); in dualsense_parse_report()
1449 input_mt_sync_frame(ds->touchpad); in dualsense_parse_report()
1450 input_report_key(ds->touchpad, BTN_LEFT, ds_report->buttons[2] & DS_BUTTONS2_TOUCHPAD); in dualsense_parse_report()
1451 input_sync(ds->touchpad); in dualsense_parse_report()
1453 battery_data = ds_report->status & DS_STATUS_BATTERY_CAPACITY; in dualsense_parse_report()
1454 charging_status = (ds_report->status & DS_STATUS_CHARGING) >> DS_STATUS_CHARGING_SHIFT; in dualsense_parse_report()
1460 * 0 = 0-9%, 1 = 10-19%, .. and 10 = 100% in dualsense_parse_report()
1484 spin_lock_irqsave(&ps_dev->lock, flags); in dualsense_parse_report()
1485 ps_dev->battery_capacity = battery_capacity; in dualsense_parse_report()
1486 ps_dev->battery_status = battery_status; in dualsense_parse_report()
1487 spin_unlock_irqrestore(&ps_dev->lock, flags); in dualsense_parse_report()
1498 if (effect->type != FF_RUMBLE) in dualsense_play_effect()
1501 spin_lock_irqsave(&ds->base.lock, flags); in dualsense_play_effect()
1502 ds->update_rumble = true; in dualsense_play_effect()
1503 ds->motor_left = effect->u.rumble.strong_magnitude / 256; in dualsense_play_effect()
1504 ds->motor_right = effect->u.rumble.weak_magnitude / 256; in dualsense_play_effect()
1505 spin_unlock_irqrestore(&ds->base.lock, flags); in dualsense_play_effect()
1516 spin_lock_irqsave(&ds->base.lock, flags); in dualsense_remove()
1517 ds->output_worker_initialized = false; in dualsense_remove()
1518 spin_unlock_irqrestore(&ds->base.lock, flags); in dualsense_remove()
1520 cancel_work_sync(&ds->output_worker); in dualsense_remove()
1530 return -ENOMEM; in dualsense_reset_leds()
1540 report.common->valid_flag2 = DS_OUTPUT_VALID_FLAG2_LIGHTBAR_SETUP_CONTROL_ENABLE; in dualsense_reset_leds()
1541 report.common->lightbar_setup = DS_OUTPUT_LIGHTBAR_SETUP_LIGHT_OUT; /* Fade light out. */ in dualsense_reset_leds()
1552 spin_lock_irqsave(&ds->base.lock, flags); in dualsense_set_lightbar()
1553 ds->update_lightbar = true; in dualsense_set_lightbar()
1554 ds->lightbar_red = red; in dualsense_set_lightbar()
1555 ds->lightbar_green = green; in dualsense_set_lightbar()
1556 ds->lightbar_blue = blue; in dualsense_set_lightbar()
1557 spin_unlock_irqrestore(&ds->base.lock, flags); in dualsense_set_lightbar()
1567 * across the LEDs, so e.g. player 1 would be "--x--" with x being 'on'. in dualsense_set_player_leds()
1578 uint8_t player_id = ds->base.player_id % ARRAY_SIZE(player_ids); in dualsense_set_player_leds()
1580 ds->update_player_leds = true; in dualsense_set_player_leds()
1581 ds->player_leds_state = player_ids[player_id]; in dualsense_set_player_leds()
1605 ds = devm_kzalloc(&hdev->dev, sizeof(*ds), GFP_KERNEL); in dualsense_create()
1607 return ERR_PTR(-ENOMEM); in dualsense_create()
1611 * hid-generic vs hid-playstation axis and button mapping. in dualsense_create()
1613 hdev->version |= HID_PLAYSTATION_VERSION_PATCH; in dualsense_create()
1615 ps_dev = &ds->base; in dualsense_create()
1616 ps_dev->hdev = hdev; in dualsense_create()
1617 spin_lock_init(&ps_dev->lock); in dualsense_create()
1618 ps_dev->battery_capacity = 100; /* initial value until parse_report. */ in dualsense_create()
1619 ps_dev->battery_status = POWER_SUPPLY_STATUS_UNKNOWN; in dualsense_create()
1620 ps_dev->parse_report = dualsense_parse_report; in dualsense_create()
1621 ps_dev->remove = dualsense_remove; in dualsense_create()
1622 INIT_WORK(&ds->output_worker, dualsense_output_worker); in dualsense_create()
1623 ds->output_worker_initialized = true; in dualsense_create()
1627 ds->output_report_dmabuf = devm_kzalloc(&hdev->dev, max_output_report_size, GFP_KERNEL); in dualsense_create()
1628 if (!ds->output_report_dmabuf) in dualsense_create()
1629 return ERR_PTR(-ENOMEM); in dualsense_create()
1636 snprintf(hdev->uniq, sizeof(hdev->uniq), "%pMR", ds->base.mac_address); in dualsense_create()
1652 if (hdev->product == USB_DEVICE_ID_SONY_PS5_CONTROLLER) { in dualsense_create()
1654 ds->use_vibration_v2 = ds->update_version >= DS_FEATURE_VERSION(2, 21); in dualsense_create()
1655 } else if (hdev->product == USB_DEVICE_ID_SONY_PS5_CONTROLLER_2) { in dualsense_create()
1656 ds->use_vibration_v2 = true; in dualsense_create()
1669 ds->gamepad = ps_gamepad_create(hdev, dualsense_play_effect); in dualsense_create()
1670 if (IS_ERR(ds->gamepad)) { in dualsense_create()
1671 ret = PTR_ERR(ds->gamepad); in dualsense_create()
1675 ps_dev->input_dev_name = dev_name(&ds->gamepad->dev); in dualsense_create()
1677 ds->sensors = ps_sensors_create(hdev, DS_ACC_RANGE, DS_ACC_RES_PER_G, in dualsense_create()
1679 if (IS_ERR(ds->sensors)) { in dualsense_create()
1680 ret = PTR_ERR(ds->sensors); in dualsense_create()
1684 ds->touchpad = ps_touchpad_create(hdev, DS_TOUCHPAD_WIDTH, DS_TOUCHPAD_HEIGHT, 2); in dualsense_create()
1685 if (IS_ERR(ds->touchpad)) { in dualsense_create()
1686 ret = PTR_ERR(ds->touchpad); in dualsense_create()
1703 ret = ps_lightbar_register(ps_dev, &ds->lightbar, dualsense_lightbar_set_brightness); in dualsense_create()
1713 ret = ps_led_register(ps_dev, &ds->player_leds[i], led_info); in dualsense_create()
1732 ds->base.hw_version, ds->base.fw_version); in dualsense_create()
1734 return &ds->base; in dualsense_create()
1752 * dongle as disabled. We will re-enable the dongle if a new in dualshock4_dongle_calibration_work()
1756 hid_err(ds4->base.hdev, "DualShock 4 USB dongle: calibration failed, disabling device\n"); in dualshock4_dongle_calibration_work()
1759 hid_info(ds4->base.hdev, "DualShock 4 USB dongle: calibration completed\n"); in dualshock4_dongle_calibration_work()
1763 spin_lock_irqsave(&ds4->base.lock, flags); in dualshock4_dongle_calibration_work()
1764 ds4->dongle_state = dongle_state; in dualshock4_dongle_calibration_work()
1765 spin_unlock_irqrestore(&ds4->base.lock, flags); in dualshock4_dongle_calibration_work()
1770 struct hid_device *hdev = ds4->base.hdev; in dualshock4_get_calibration_data()
1784 if (ds4->base.hdev->bus == BUS_USB) { in dualshock4_get_calibration_data()
1789 ret = -ENOMEM; in dualshock4_get_calibration_data()
1809 ret = -EILSEQ; in dualshock4_get_calibration_data()
1818 ret = -ENOMEM; in dualshock4_get_calibration_data()
1831 /* Transfer succeeded - parse the calibration data received. */ in dualshock4_get_calibration_data()
1835 if (ds4->base.hdev->bus == BUS_USB) { in dualshock4_get_calibration_data()
1868 ds4->gyro_calib_data[0].abs_code = ABS_RX; in dualshock4_get_calibration_data()
1869 ds4->gyro_calib_data[0].bias = 0; in dualshock4_get_calibration_data()
1870 ds4->gyro_calib_data[0].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S; in dualshock4_get_calibration_data()
1871 ds4->gyro_calib_data[0].sens_denom = abs(gyro_pitch_plus - gyro_pitch_bias) + in dualshock4_get_calibration_data()
1872 abs(gyro_pitch_minus - gyro_pitch_bias); in dualshock4_get_calibration_data()
1874 ds4->gyro_calib_data[1].abs_code = ABS_RY; in dualshock4_get_calibration_data()
1875 ds4->gyro_calib_data[1].bias = 0; in dualshock4_get_calibration_data()
1876 ds4->gyro_calib_data[1].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S; in dualshock4_get_calibration_data()
1877 ds4->gyro_calib_data[1].sens_denom = abs(gyro_yaw_plus - gyro_yaw_bias) + in dualshock4_get_calibration_data()
1878 abs(gyro_yaw_minus - gyro_yaw_bias); in dualshock4_get_calibration_data()
1880 ds4->gyro_calib_data[2].abs_code = ABS_RZ; in dualshock4_get_calibration_data()
1881 ds4->gyro_calib_data[2].bias = 0; in dualshock4_get_calibration_data()
1882 ds4->gyro_calib_data[2].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S; in dualshock4_get_calibration_data()
1883 ds4->gyro_calib_data[2].sens_denom = abs(gyro_roll_plus - gyro_roll_bias) + in dualshock4_get_calibration_data()
1884 abs(gyro_roll_minus - gyro_roll_bias); in dualshock4_get_calibration_data()
1890 range_2g = acc_x_plus - acc_x_minus; in dualshock4_get_calibration_data()
1891 ds4->accel_calib_data[0].abs_code = ABS_X; in dualshock4_get_calibration_data()
1892 ds4->accel_calib_data[0].bias = acc_x_plus - range_2g / 2; in dualshock4_get_calibration_data()
1893 ds4->accel_calib_data[0].sens_numer = 2*DS4_ACC_RES_PER_G; in dualshock4_get_calibration_data()
1894 ds4->accel_calib_data[0].sens_denom = range_2g; in dualshock4_get_calibration_data()
1896 range_2g = acc_y_plus - acc_y_minus; in dualshock4_get_calibration_data()
1897 ds4->accel_calib_data[1].abs_code = ABS_Y; in dualshock4_get_calibration_data()
1898 ds4->accel_calib_data[1].bias = acc_y_plus - range_2g / 2; in dualshock4_get_calibration_data()
1899 ds4->accel_calib_data[1].sens_numer = 2*DS4_ACC_RES_PER_G; in dualshock4_get_calibration_data()
1900 ds4->accel_calib_data[1].sens_denom = range_2g; in dualshock4_get_calibration_data()
1902 range_2g = acc_z_plus - acc_z_minus; in dualshock4_get_calibration_data()
1903 ds4->accel_calib_data[2].abs_code = ABS_Z; in dualshock4_get_calibration_data()
1904 ds4->accel_calib_data[2].bias = acc_z_plus - range_2g / 2; in dualshock4_get_calibration_data()
1905 ds4->accel_calib_data[2].sens_numer = 2*DS4_ACC_RES_PER_G; in dualshock4_get_calibration_data()
1906 ds4->accel_calib_data[2].sens_denom = range_2g; in dualshock4_get_calibration_data()
1914 for (i = 0; i < ARRAY_SIZE(ds4->gyro_calib_data); i++) { in dualshock4_get_calibration_data()
1915 if (ds4->gyro_calib_data[i].sens_denom == 0) { in dualshock4_get_calibration_data()
1916 ds4->gyro_calib_data[i].abs_code = ABS_RX + i; in dualshock4_get_calibration_data()
1918 ds4->gyro_calib_data[i].abs_code); in dualshock4_get_calibration_data()
1919 ds4->gyro_calib_data[i].bias = 0; in dualshock4_get_calibration_data()
1920 ds4->gyro_calib_data[i].sens_numer = DS4_GYRO_RANGE; in dualshock4_get_calibration_data()
1921 ds4->gyro_calib_data[i].sens_denom = S16_MAX; in dualshock4_get_calibration_data()
1930 for (i = 0; i < ARRAY_SIZE(ds4->accel_calib_data); i++) { in dualshock4_get_calibration_data()
1931 if (ds4->accel_calib_data[i].sens_denom == 0) { in dualshock4_get_calibration_data()
1932 ds4->accel_calib_data[i].abs_code = ABS_X + i; in dualshock4_get_calibration_data()
1934 ds4->accel_calib_data[i].abs_code); in dualshock4_get_calibration_data()
1935 ds4->accel_calib_data[i].bias = 0; in dualshock4_get_calibration_data()
1936 ds4->accel_calib_data[i].sens_numer = DS4_ACC_RANGE; in dualshock4_get_calibration_data()
1937 ds4->accel_calib_data[i].sens_denom = S16_MAX; in dualshock4_get_calibration_data()
1951 return -ENOMEM; in dualshock4_get_firmware_info()
1956 ret = ps_get_report(ds4->base.hdev, DS4_FEATURE_REPORT_FIRMWARE_INFO, buf, in dualshock4_get_firmware_info()
1959 hid_err(ds4->base.hdev, "Failed to retrieve DualShock4 firmware info: %d\n", ret); in dualshock4_get_firmware_info()
1963 ds4->base.hw_version = get_unaligned_le16(&buf[35]); in dualshock4_get_firmware_info()
1964 ds4->base.fw_version = get_unaligned_le16(&buf[41]); in dualshock4_get_firmware_info()
1973 struct hid_device *hdev = ds4->base.hdev; in dualshock4_get_mac_address()
1977 if (hdev->bus == BUS_USB) { in dualshock4_get_mac_address()
1980 return -ENOMEM; in dualshock4_get_mac_address()
1989 memcpy(ds4->base.mac_address, &buf[1], sizeof(ds4->base.mac_address)); in dualshock4_get_mac_address()
1992 if (strlen(hdev->uniq) != 17) in dualshock4_get_mac_address()
1993 return -EINVAL; in dualshock4_get_mac_address()
1995 ret = sscanf(hdev->uniq, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", in dualshock4_get_mac_address()
1996 &ds4->base.mac_address[5], &ds4->base.mac_address[4], in dualshock4_get_mac_address()
1997 &ds4->base.mac_address[3], &ds4->base.mac_address[2], in dualshock4_get_mac_address()
1998 &ds4->base.mac_address[1], &ds4->base.mac_address[0]); in dualshock4_get_mac_address()
2000 if (ret != sizeof(ds4->base.mac_address)) in dualshock4_get_mac_address()
2001 return -EINVAL; in dualshock4_get_mac_address()
2013 struct hid_device *hdev = to_hid_device(led->dev->parent); in dualshock4_led_get_brightness()
2017 led_index = led - ds4->lightbar_leds; in dualshock4_led_get_brightness()
2020 return ds4->lightbar_red; in dualshock4_led_get_brightness()
2022 return ds4->lightbar_green; in dualshock4_led_get_brightness()
2024 return ds4->lightbar_blue; in dualshock4_led_get_brightness()
2026 return ds4->lightbar_enabled; in dualshock4_led_get_brightness()
2029 return -1; in dualshock4_led_get_brightness()
2035 struct hid_device *hdev = to_hid_device(led->dev->parent); in dualshock4_led_set_blink()
2039 spin_lock_irqsave(&ds4->base.lock, flags); in dualshock4_led_set_blink()
2043 ds4->lightbar_blink_on = 50; in dualshock4_led_set_blink()
2044 ds4->lightbar_blink_off = 50; in dualshock4_led_set_blink()
2047 ds4->lightbar_blink_on = min_t(unsigned long, *delay_on/10, DS4_LIGHTBAR_MAX_BLINK); in dualshock4_led_set_blink()
2048 ds4->lightbar_blink_off = min_t(unsigned long, *delay_off/10, DS4_LIGHTBAR_MAX_BLINK); in dualshock4_led_set_blink()
2051 ds4->update_lightbar_blink = true; in dualshock4_led_set_blink()
2053 spin_unlock_irqrestore(&ds4->base.lock, flags); in dualshock4_led_set_blink()
2058 *delay_on = ds4->lightbar_blink_on * 10; in dualshock4_led_set_blink()
2059 *delay_off = ds4->lightbar_blink_off * 10; in dualshock4_led_set_blink()
2066 struct hid_device *hdev = to_hid_device(led->dev->parent); in dualshock4_led_set_brightness()
2071 spin_lock_irqsave(&ds4->base.lock, flags); in dualshock4_led_set_brightness()
2073 led_index = led - ds4->lightbar_leds; in dualshock4_led_set_brightness()
2076 ds4->lightbar_red = value; in dualshock4_led_set_brightness()
2079 ds4->lightbar_green = value; in dualshock4_led_set_brightness()
2082 ds4->lightbar_blue = value; in dualshock4_led_set_brightness()
2085 ds4->lightbar_enabled = !!value; in dualshock4_led_set_brightness()
2088 if (!ds4->lightbar_enabled) { in dualshock4_led_set_brightness()
2089 ds4->lightbar_blink_off = 0; in dualshock4_led_set_brightness()
2090 ds4->lightbar_blink_on = 0; in dualshock4_led_set_brightness()
2091 ds4->update_lightbar_blink = true; in dualshock4_led_set_brightness()
2095 ds4->update_lightbar = true; in dualshock4_led_set_brightness()
2097 spin_unlock_irqrestore(&ds4->base.lock, flags); in dualshock4_led_set_brightness()
2107 struct hid_device *hdev = ds4->base.hdev; in dualshock4_init_output_report()
2109 if (hdev->bus == BUS_BLUETOOTH) { in dualshock4_init_output_report()
2113 bt->report_id = DS4_OUTPUT_REPORT_BT; in dualshock4_init_output_report()
2115 rp->data = buf; in dualshock4_init_output_report()
2116 rp->len = sizeof(*bt); in dualshock4_init_output_report()
2117 rp->bt = bt; in dualshock4_init_output_report()
2118 rp->usb = NULL; in dualshock4_init_output_report()
2119 rp->common = &bt->common; in dualshock4_init_output_report()
2124 usb->report_id = DS4_OUTPUT_REPORT_USB; in dualshock4_init_output_report()
2126 rp->data = buf; in dualshock4_init_output_report()
2127 rp->len = sizeof(*usb); in dualshock4_init_output_report()
2128 rp->bt = NULL; in dualshock4_init_output_report()
2129 rp->usb = usb; in dualshock4_init_output_report()
2130 rp->common = &usb->common; in dualshock4_init_output_report()
2141 dualshock4_init_output_report(ds4, &report, ds4->output_report_dmabuf); in dualshock4_output_worker()
2144 spin_lock_irqsave(&ds4->base.lock, flags); in dualshock4_output_worker()
2154 * ds4->valid_flag0 >= 0x03 in dualshock4_output_worker()
2156 * Hopefully this will maximise compatibility with third-party pads. in dualshock4_output_worker()
2161 if (ds4->update_rumble || ds4->update_lightbar) { in dualshock4_output_worker()
2162 ds4->update_rumble = true; /* 0x01 */ in dualshock4_output_worker()
2163 ds4->update_lightbar = true; /* 0x02 */ in dualshock4_output_worker()
2166 if (ds4->update_rumble) { in dualshock4_output_worker()
2168 common->valid_flag0 |= DS4_OUTPUT_VALID_FLAG0_MOTOR; in dualshock4_output_worker()
2169 common->motor_left = ds4->motor_left; in dualshock4_output_worker()
2170 common->motor_right = ds4->motor_right; in dualshock4_output_worker()
2171 ds4->update_rumble = false; in dualshock4_output_worker()
2174 if (ds4->update_lightbar) { in dualshock4_output_worker()
2175 common->valid_flag0 |= DS4_OUTPUT_VALID_FLAG0_LED; in dualshock4_output_worker()
2176 /* Comptabile behavior with hid-sony, which used a dummy global LED to in dualshock4_output_worker()
2180 common->lightbar_red = ds4->lightbar_enabled ? ds4->lightbar_red : 0; in dualshock4_output_worker()
2181 common->lightbar_green = ds4->lightbar_enabled ? ds4->lightbar_green : 0; in dualshock4_output_worker()
2182 common->lightbar_blue = ds4->lightbar_enabled ? ds4->lightbar_blue : 0; in dualshock4_output_worker()
2183 ds4->update_lightbar = false; in dualshock4_output_worker()
2186 if (ds4->update_lightbar_blink) { in dualshock4_output_worker()
2187 common->valid_flag0 |= DS4_OUTPUT_VALID_FLAG0_LED_BLINK; in dualshock4_output_worker()
2188 common->lightbar_blink_on = ds4->lightbar_blink_on; in dualshock4_output_worker()
2189 common->lightbar_blink_off = ds4->lightbar_blink_off; in dualshock4_output_worker()
2190 ds4->update_lightbar_blink = false; in dualshock4_output_worker()
2193 spin_unlock_irqrestore(&ds4->base.lock, flags); in dualshock4_output_worker()
2203 report.bt->hw_control = DS4_OUTPUT_HWCTL_HID | DS4_OUTPUT_HWCTL_CRC32; in dualshock4_output_worker()
2205 if (ds4->update_bt_poll_interval) { in dualshock4_output_worker()
2206 report.bt->hw_control |= ds4->bt_poll_interval; in dualshock4_output_worker()
2207 ds4->update_bt_poll_interval = false; in dualshock4_output_worker()
2211 crc = ~crc32_le(crc, report.data, report.len - 4); in dualshock4_output_worker()
2213 report.bt->crc32 = cpu_to_le32(crc); in dualshock4_output_worker()
2216 hid_hw_output_report(ds4->base.hdev, report.data, report.len); in dualshock4_output_worker()
2222 struct hid_device *hdev = ps_dev->hdev; in dualshock4_parse_report()
2237 if (hdev->bus == BUS_USB && report->id == DS4_INPUT_REPORT_USB && in dualshock4_parse_report()
2241 ds4_report = &usb->common; in dualshock4_parse_report()
2242 num_touch_reports = usb->num_touch_reports; in dualshock4_parse_report()
2243 touch_reports = usb->touch_reports; in dualshock4_parse_report()
2244 } else if (hdev->bus == BUS_BLUETOOTH && report->id == DS4_INPUT_REPORT_BT && in dualshock4_parse_report()
2247 uint32_t report_crc = get_unaligned_le32(&bt->crc32); in dualshock4_parse_report()
2250 if (!ps_check_crc32(PS_INPUT_CRC32_SEED, data, size - 4, report_crc)) { in dualshock4_parse_report()
2252 return -EILSEQ; in dualshock4_parse_report()
2255 ds4_report = &bt->common; in dualshock4_parse_report()
2256 num_touch_reports = bt->num_touch_reports; in dualshock4_parse_report()
2257 touch_reports = bt->touch_reports; in dualshock4_parse_report()
2258 } else if (hdev->bus == BUS_BLUETOOTH && in dualshock4_parse_report()
2259 report->id == DS4_INPUT_REPORT_BT_MINIMAL && in dualshock4_parse_report()
2261 /* Some third-party pads never switch to the full 0x11 report. in dualshock4_parse_report()
2271 hid_err(hdev, "Unhandled reportID=%d\n", report->id); in dualshock4_parse_report()
2272 return -1; in dualshock4_parse_report()
2275 input_report_abs(ds4->gamepad, ABS_X, ds4_report->x); in dualshock4_parse_report()
2276 input_report_abs(ds4->gamepad, ABS_Y, ds4_report->y); in dualshock4_parse_report()
2277 input_report_abs(ds4->gamepad, ABS_RX, ds4_report->rx); in dualshock4_parse_report()
2278 input_report_abs(ds4->gamepad, ABS_RY, ds4_report->ry); in dualshock4_parse_report()
2279 input_report_abs(ds4->gamepad, ABS_Z, ds4_report->z); in dualshock4_parse_report()
2280 input_report_abs(ds4->gamepad, ABS_RZ, ds4_report->rz); in dualshock4_parse_report()
2282 value = ds4_report->buttons[0] & DS_BUTTONS0_HAT_SWITCH; in dualshock4_parse_report()
2285 input_report_abs(ds4->gamepad, ABS_HAT0X, ps_gamepad_hat_mapping[value].x); in dualshock4_parse_report()
2286 input_report_abs(ds4->gamepad, ABS_HAT0Y, ps_gamepad_hat_mapping[value].y); in dualshock4_parse_report()
2288 input_report_key(ds4->gamepad, BTN_WEST, ds4_report->buttons[0] & DS_BUTTONS0_SQUARE); in dualshock4_parse_report()
2289 input_report_key(ds4->gamepad, BTN_SOUTH, ds4_report->buttons[0] & DS_BUTTONS0_CROSS); in dualshock4_parse_report()
2290 input_report_key(ds4->gamepad, BTN_EAST, ds4_report->buttons[0] & DS_BUTTONS0_CIRCLE); in dualshock4_parse_report()
2291 input_report_key(ds4->gamepad, BTN_NORTH, ds4_report->buttons[0] & DS_BUTTONS0_TRIANGLE); in dualshock4_parse_report()
2292 input_report_key(ds4->gamepad, BTN_TL, ds4_report->buttons[1] & DS_BUTTONS1_L1); in dualshock4_parse_report()
2293 input_report_key(ds4->gamepad, BTN_TR, ds4_report->buttons[1] & DS_BUTTONS1_R1); in dualshock4_parse_report()
2294 input_report_key(ds4->gamepad, BTN_TL2, ds4_report->buttons[1] & DS_BUTTONS1_L2); in dualshock4_parse_report()
2295 input_report_key(ds4->gamepad, BTN_TR2, ds4_report->buttons[1] & DS_BUTTONS1_R2); in dualshock4_parse_report()
2296 input_report_key(ds4->gamepad, BTN_SELECT, ds4_report->buttons[1] & DS_BUTTONS1_CREATE); in dualshock4_parse_report()
2297 input_report_key(ds4->gamepad, BTN_START, ds4_report->buttons[1] & DS_BUTTONS1_OPTIONS); in dualshock4_parse_report()
2298 input_report_key(ds4->gamepad, BTN_THUMBL, ds4_report->buttons[1] & DS_BUTTONS1_L3); in dualshock4_parse_report()
2299 input_report_key(ds4->gamepad, BTN_THUMBR, ds4_report->buttons[1] & DS_BUTTONS1_R3); in dualshock4_parse_report()
2300 input_report_key(ds4->gamepad, BTN_MODE, ds4_report->buttons[2] & DS_BUTTONS2_PS_HOME); in dualshock4_parse_report()
2301 input_sync(ds4->gamepad); in dualshock4_parse_report()
2307 for (i = 0; i < ARRAY_SIZE(ds4_report->gyro); i++) { in dualshock4_parse_report()
2308 int raw_data = (short)le16_to_cpu(ds4_report->gyro[i]); in dualshock4_parse_report()
2309 int calib_data = mult_frac(ds4->gyro_calib_data[i].sens_numer, in dualshock4_parse_report()
2310 raw_data, ds4->gyro_calib_data[i].sens_denom); in dualshock4_parse_report()
2312 input_report_abs(ds4->sensors, ds4->gyro_calib_data[i].abs_code, calib_data); in dualshock4_parse_report()
2316 for (i = 0; i < ARRAY_SIZE(ds4_report->accel); i++) { in dualshock4_parse_report()
2317 int raw_data = (short)le16_to_cpu(ds4_report->accel[i]); in dualshock4_parse_report()
2318 int calib_data = mult_frac(ds4->accel_calib_data[i].sens_numer, in dualshock4_parse_report()
2319 raw_data - ds4->accel_calib_data[i].bias, in dualshock4_parse_report()
2320 ds4->accel_calib_data[i].sens_denom); in dualshock4_parse_report()
2322 input_report_abs(ds4->sensors, ds4->accel_calib_data[i].abs_code, calib_data); in dualshock4_parse_report()
2326 sensor_timestamp = le16_to_cpu(ds4_report->sensor_timestamp); in dualshock4_parse_report()
2327 if (!ds4->sensor_timestamp_initialized) { in dualshock4_parse_report()
2328 ds4->sensor_timestamp_us = DIV_ROUND_CLOSEST(sensor_timestamp*16, 3); in dualshock4_parse_report()
2329 ds4->sensor_timestamp_initialized = true; in dualshock4_parse_report()
2333 if (ds4->prev_sensor_timestamp > sensor_timestamp) in dualshock4_parse_report()
2334 delta = (U16_MAX - ds4->prev_sensor_timestamp + sensor_timestamp + 1); in dualshock4_parse_report()
2336 delta = sensor_timestamp - ds4->prev_sensor_timestamp; in dualshock4_parse_report()
2337 ds4->sensor_timestamp_us += DIV_ROUND_CLOSEST(delta*16, 3); in dualshock4_parse_report()
2339 ds4->prev_sensor_timestamp = sensor_timestamp; in dualshock4_parse_report()
2340 input_event(ds4->sensors, EV_MSC, MSC_TIMESTAMP, ds4->sensor_timestamp_us); in dualshock4_parse_report()
2341 input_sync(ds4->sensors); in dualshock4_parse_report()
2346 for (j = 0; j < ARRAY_SIZE(touch_report->points); j++) { in dualshock4_parse_report()
2347 struct dualshock4_touch_point *point = &touch_report->points[j]; in dualshock4_parse_report()
2348 bool active = (point->contact & DS4_TOUCH_POINT_INACTIVE) ? false : true; in dualshock4_parse_report()
2350 input_mt_slot(ds4->touchpad, j); in dualshock4_parse_report()
2351 input_mt_report_slot_state(ds4->touchpad, MT_TOOL_FINGER, active); in dualshock4_parse_report()
2354 int x = (point->x_hi << 8) | point->x_lo; in dualshock4_parse_report()
2355 int y = (point->y_hi << 4) | point->y_lo; in dualshock4_parse_report()
2357 input_report_abs(ds4->touchpad, ABS_MT_POSITION_X, x); in dualshock4_parse_report()
2358 input_report_abs(ds4->touchpad, ABS_MT_POSITION_Y, y); in dualshock4_parse_report()
2361 input_mt_sync_frame(ds4->touchpad); in dualshock4_parse_report()
2362 input_sync(ds4->touchpad); in dualshock4_parse_report()
2364 input_report_key(ds4->touchpad, BTN_LEFT, ds4_report->buttons[2] & DS_BUTTONS2_TOUCHPAD); in dualshock4_parse_report()
2369 * - 0:10: percentage in units of 10%. in dualshock4_parse_report()
2371 * - 0-10: percentage in units of 10%. in dualshock4_parse_report()
2372 * - 11: battery is full in dualshock4_parse_report()
2373 * - 14: not charging due to Voltage or temperature error in dualshock4_parse_report()
2374 * - 15: charge error in dualshock4_parse_report()
2376 if (ds4_report->status[0] & DS4_STATUS0_CABLE_STATE) { in dualshock4_parse_report()
2377 uint8_t battery_data = ds4_report->status[0] & DS4_STATUS0_BATTERY_CAPACITY; in dualshock4_parse_report()
2380 /* Take the mid-point for each battery capacity value, in dualshock4_parse_report()
2381 * because on the hardware side 0 = 0-9%, 1=10-19%, etc. in dualshock4_parse_report()
2398 uint8_t battery_data = ds4_report->status[0] & DS4_STATUS0_BATTERY_CAPACITY; in dualshock4_parse_report()
2408 spin_lock_irqsave(&ps_dev->lock, flags); in dualshock4_parse_report()
2409 ps_dev->battery_capacity = battery_capacity; in dualshock4_parse_report()
2410 ps_dev->battery_status = battery_status; in dualshock4_parse_report()
2411 spin_unlock_irqrestore(&ps_dev->lock, flags); in dualshock4_parse_report()
2431 connected = ds4_report->status[1] & DS4_STATUS1_DONGLE_STATE ? false : true; in dualshock4_dongle_parse_report()
2433 if (ds4->dongle_state == DONGLE_DISCONNECTED && connected) { in dualshock4_dongle_parse_report()
2434 hid_info(ps_dev->hdev, "DualShock 4 USB dongle: controller connected\n"); in dualshock4_dongle_parse_report()
2438 spin_lock_irqsave(&ps_dev->lock, flags); in dualshock4_dongle_parse_report()
2439 ds4->dongle_state = DONGLE_CALIBRATING; in dualshock4_dongle_parse_report()
2440 spin_unlock_irqrestore(&ps_dev->lock, flags); in dualshock4_dongle_parse_report()
2442 schedule_work(&ds4->dongle_hotplug_worker); in dualshock4_dongle_parse_report()
2448 } else if ((ds4->dongle_state == DONGLE_CONNECTED || in dualshock4_dongle_parse_report()
2449 ds4->dongle_state == DONGLE_DISABLED) && !connected) { in dualshock4_dongle_parse_report()
2450 hid_info(ps_dev->hdev, "DualShock 4 USB dongle: controller disconnected\n"); in dualshock4_dongle_parse_report()
2452 spin_lock_irqsave(&ps_dev->lock, flags); in dualshock4_dongle_parse_report()
2453 ds4->dongle_state = DONGLE_DISCONNECTED; in dualshock4_dongle_parse_report()
2454 spin_unlock_irqrestore(&ps_dev->lock, flags); in dualshock4_dongle_parse_report()
2458 } else if (ds4->dongle_state == DONGLE_CALIBRATING || in dualshock4_dongle_parse_report()
2459 ds4->dongle_state == DONGLE_DISABLED || in dualshock4_dongle_parse_report()
2460 ds4->dongle_state == DONGLE_DISCONNECTED) { in dualshock4_dongle_parse_report()
2478 if (effect->type != FF_RUMBLE) in dualshock4_play_effect()
2481 spin_lock_irqsave(&ds4->base.lock, flags); in dualshock4_play_effect()
2482 ds4->update_rumble = true; in dualshock4_play_effect()
2483 ds4->motor_left = effect->u.rumble.strong_magnitude / 256; in dualshock4_play_effect()
2484 ds4->motor_right = effect->u.rumble.weak_magnitude / 256; in dualshock4_play_effect()
2485 spin_unlock_irqrestore(&ds4->base.lock, flags); in dualshock4_play_effect()
2496 spin_lock_irqsave(&ds4->base.lock, flags); in dualshock4_remove()
2497 ds4->output_worker_initialized = false; in dualshock4_remove()
2498 spin_unlock_irqrestore(&ds4->base.lock, flags); in dualshock4_remove()
2500 cancel_work_sync(&ds4->output_worker); in dualshock4_remove()
2502 if (ps_dev->hdev->product == USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE) in dualshock4_remove()
2503 cancel_work_sync(&ds4->dongle_hotplug_worker); in dualshock4_remove()
2510 spin_lock_irqsave(&ds4->base.lock, flags); in dualshock4_schedule_work()
2511 if (ds4->output_worker_initialized) in dualshock4_schedule_work()
2512 schedule_work(&ds4->output_worker); in dualshock4_schedule_work()
2513 spin_unlock_irqrestore(&ds4->base.lock, flags); in dualshock4_schedule_work()
2518 ds4->bt_poll_interval = interval; in dualshock4_set_bt_poll_interval()
2519 ds4->update_bt_poll_interval = true; in dualshock4_set_bt_poll_interval()
2536 uint8_t player_id = ds4->base.player_id % ARRAY_SIZE(player_colors); in dualshock4_set_default_lightbar_colors()
2538 ds4->lightbar_enabled = true; in dualshock4_set_default_lightbar_colors()
2539 ds4->lightbar_red = player_colors[player_id][0]; in dualshock4_set_default_lightbar_colors()
2540 ds4->lightbar_green = player_colors[player_id][1]; in dualshock4_set_default_lightbar_colors()
2541 ds4->lightbar_blue = player_colors[player_id][2]; in dualshock4_set_default_lightbar_colors()
2543 ds4->update_lightbar = true; in dualshock4_set_default_lightbar_colors()
2554 /* The DualShock4 has an RGB lightbar, which the original hid-sony driver in dualshock4_create()
2556 * Ideally this should have used the multi-color LED class, which didn't exist in dualshock4_create()
2571 ds4 = devm_kzalloc(&hdev->dev, sizeof(*ds4), GFP_KERNEL); in dualshock4_create()
2573 return ERR_PTR(-ENOMEM); in dualshock4_create()
2577 * hid-generic vs hid-playstation axis and button mapping. in dualshock4_create()
2579 hdev->version |= HID_PLAYSTATION_VERSION_PATCH; in dualshock4_create()
2581 ps_dev = &ds4->base; in dualshock4_create()
2582 ps_dev->hdev = hdev; in dualshock4_create()
2583 spin_lock_init(&ps_dev->lock); in dualshock4_create()
2584 ps_dev->battery_capacity = 100; /* initial value until parse_report. */ in dualshock4_create()
2585 ps_dev->battery_status = POWER_SUPPLY_STATUS_UNKNOWN; in dualshock4_create()
2586 ps_dev->parse_report = dualshock4_parse_report; in dualshock4_create()
2587 ps_dev->remove = dualshock4_remove; in dualshock4_create()
2588 INIT_WORK(&ds4->output_worker, dualshock4_output_worker); in dualshock4_create()
2589 ds4->output_worker_initialized = true; in dualshock4_create()
2593 ds4->output_report_dmabuf = devm_kzalloc(&hdev->dev, max_output_report_size, GFP_KERNEL); in dualshock4_create()
2594 if (!ds4->output_report_dmabuf) in dualshock4_create()
2595 return ERR_PTR(-ENOMEM); in dualshock4_create()
2597 if (hdev->product == USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE) { in dualshock4_create()
2598 ds4->dongle_state = DONGLE_DISCONNECTED; in dualshock4_create()
2599 INIT_WORK(&ds4->dongle_hotplug_worker, dualshock4_dongle_calibration_work); in dualshock4_create()
2602 ps_dev->parse_report = dualshock4_dongle_parse_report; in dualshock4_create()
2610 snprintf(hdev->uniq, sizeof(hdev->uniq), "%pMR", ds4->base.mac_address); in dualshock4_create()
2628 ds4->gamepad = ps_gamepad_create(hdev, dualshock4_play_effect); in dualshock4_create()
2629 if (IS_ERR(ds4->gamepad)) { in dualshock4_create()
2630 ret = PTR_ERR(ds4->gamepad); in dualshock4_create()
2635 ps_dev->input_dev_name = dev_name(&ds4->gamepad->dev); in dualshock4_create()
2637 ds4->sensors = ps_sensors_create(hdev, DS4_ACC_RANGE, DS4_ACC_RES_PER_G, in dualshock4_create()
2639 if (IS_ERR(ds4->sensors)) { in dualshock4_create()
2640 ret = PTR_ERR(ds4->sensors); in dualshock4_create()
2644 ds4->touchpad = ps_touchpad_create(hdev, DS4_TOUCHPAD_WIDTH, DS4_TOUCHPAD_HEIGHT, 2); in dualshock4_create()
2645 if (IS_ERR(ds4->touchpad)) { in dualshock4_create()
2646 ret = PTR_ERR(ds4->touchpad); in dualshock4_create()
2657 ret = ps_led_register(ps_dev, &ds4->lightbar_leds[i], led_info); in dualshock4_create()
2677 ds4->base.hw_version, ds4->base.fw_version); in dualshock4_create()
2678 return &ds4->base; in dualshock4_create()
2690 if (dev && dev->parse_report) in ps_raw_event()
2691 return dev->parse_report(dev, report, data, size); in ps_raw_event()
2719 if (id->driver_data == PS_TYPE_PS4_DUALSHOCK4) { in ps_probe()
2726 } else if (id->driver_data == PS_TYPE_PS5_DUALSENSE) { in ps_probe()
2751 if (dev->remove) in ps_remove()
2752 dev->remove(dev); in ps_remove()