Lines Matching +full:calibration +full:- +full:data

1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright (c) 2020-2022 Sony Interactive Entertainment
17 #include <linux/led-class-multicolor.h>
22 #include "hid-ids.h"
55 int (*parse_report)(struct ps_device *dev, struct hid_report *report, u8 *data, int size);
59 /* Calibration data for playstation motion sensors. */
131 * and any associated data is then invalid.
184 /* Calibration data for accelerometer and gyroscope. */
188 /* Timestamp for sensor data */
258 static_assert(sizeof(struct dualsense_input_report) == DS_INPUT_REPORT_USB_SIZE - 1);
260 /* Common data between DualSense BT/USB main output report. */
270 u8 headphone_volume; /* 0x0 - 0x7f */
271 u8 speaker_volume; /* 0x0 - 0xff */
272 u8 mic_volume; /* 0x0 - 0x40 */
315 u8 *data; /* Start of data */ member
318 /* Points to Bluetooth data payload in case for a Bluetooth report else NULL. */
320 /* Points to USB data payload in case for a USB report else NULL. */
349 * and any associated data is then invalid.
367 * control the interval at which Dualshock 4 reports data:
368 * 0x00 - 1ms
369 * 0x01 - 1ms
370 * 0x02 - 2ms
371 * 0x3E - 62ms
372 * 0x3F - disabled
407 /* Calibration data for accelerometer and gyroscope. */
413 /* Used during calibration. */
416 /* Timestamp for sensor data */
498 /* Common data between Bluetooth and USB DualShock4 output reports. */
538 u8 *data; /* Start of data */ member
541 /* Points to Bluetooth data payload in case for a Bluetooth report else NULL. */
543 /* Points to USB data payload in case for a USB report else NULL. */
571 {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1},
593 if (!memcmp(entry->mac_address, dev->mac_address, sizeof(dev->mac_address))) { in ps_devices_list_add()
594 hid_err(dev->hdev, "Duplicate device found for MAC address %pMR.\n", in ps_devices_list_add()
595 dev->mac_address); in ps_devices_list_add()
596 return -EEXIST; in ps_devices_list_add()
600 list_add_tail(&dev->list, &ps_devices_list); in ps_devices_list_add()
608 list_del(&dev->list); in ps_devices_list_remove()
619 dev->player_id = ret; in ps_device_set_player_id()
625 ida_free(&ps_player_id_allocator, dev->player_id); in ps_device_release_player_id()
627 dev->player_id = U32_MAX; in ps_device_release_player_id()
635 input_dev = devm_input_allocate_device(&hdev->dev); in ps_allocate_input_dev()
637 return ERR_PTR(-ENOMEM); in ps_allocate_input_dev()
639 input_dev->id.bustype = hdev->bus; in ps_allocate_input_dev()
640 input_dev->id.vendor = hdev->vendor; in ps_allocate_input_dev()
641 input_dev->id.product = hdev->product; in ps_allocate_input_dev()
642 input_dev->id.version = hdev->version; in ps_allocate_input_dev()
643 input_dev->uniq = hdev->uniq; in ps_allocate_input_dev()
646 input_dev->name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s %s", in ps_allocate_input_dev()
647 hdev->name, name_suffix); in ps_allocate_input_dev()
648 if (!input_dev->name) in ps_allocate_input_dev()
649 return ERR_PTR(-ENOMEM); in ps_allocate_input_dev()
651 input_dev->name = hdev->name; in ps_allocate_input_dev()
675 scoped_guard(spinlock_irqsave, &dev->lock) { in ps_battery_get_property()
676 battery_capacity = dev->battery_capacity; in ps_battery_get_property()
677 battery_status = dev->battery_status; in ps_battery_get_property()
682 val->intval = battery_status; in ps_battery_get_property()
685 val->intval = 1; in ps_battery_get_property()
688 val->intval = battery_capacity; in ps_battery_get_property()
691 val->intval = POWER_SUPPLY_SCOPE_DEVICE; in ps_battery_get_property()
694 ret = -EINVAL; in ps_battery_get_property()
707 dev->battery_desc.type = POWER_SUPPLY_TYPE_BATTERY; in ps_device_register_battery()
708 dev->battery_desc.properties = ps_power_supply_props; in ps_device_register_battery()
709 dev->battery_desc.num_properties = ARRAY_SIZE(ps_power_supply_props); in ps_device_register_battery()
710 dev->battery_desc.get_property = ps_battery_get_property; in ps_device_register_battery()
711 dev->battery_desc.name = devm_kasprintf(&dev->hdev->dev, GFP_KERNEL, in ps_device_register_battery()
712 "ps-controller-battery-%pMR", dev->mac_address); in ps_device_register_battery()
713 if (!dev->battery_desc.name) in ps_device_register_battery()
714 return -ENOMEM; in ps_device_register_battery()
716 battery = devm_power_supply_register(&dev->hdev->dev, &dev->battery_desc, &battery_cfg); in ps_device_register_battery()
719 hid_err(dev->hdev, "Unable to register battery device: %d\n", ret); in ps_device_register_battery()
722 dev->battery = battery; in ps_device_register_battery()
724 ret = power_supply_powers(dev->battery, &dev->hdev->dev); in ps_device_register_battery()
726 hid_err(dev->hdev, "Unable to activate battery device: %d\n", ret); in ps_device_register_battery()
733 /* Compute crc32 of HID data and compare against expected CRC. */
734 static bool ps_check_crc32(u8 seed, u8 *data, size_t len, u32 report_crc) in ps_check_crc32() argument
739 crc = ~crc32_le(crc, data, len); in ps_check_crc32()
763 input_set_abs_params(gamepad, ABS_HAT0X, -1, 1, 0, 0); in ps_gamepad_create()
764 input_set_abs_params(gamepad, ABS_HAT0Y, -1, 1, 0, 0); in ps_gamepad_create()
797 return -EINVAL; in ps_get_report()
802 return -EINVAL; in ps_get_report()
805 if (hdev->bus == BUS_BLUETOOTH && check_crc) { in ps_get_report()
807 u8 crc_offset = size - 4; in ps_get_report()
812 return -EILSEQ; in ps_get_report()
824 if (led_info->name) { in ps_led_register()
825 led->name = devm_kasprintf(&ps_dev->hdev->dev, GFP_KERNEL, "%s:%s:%s", in ps_led_register()
826 ps_dev->input_dev_name, led_info->color, in ps_led_register()
827 led_info->name); in ps_led_register()
829 /* Backwards compatible mode for hid-sony, but not compliant in ps_led_register()
832 led->name = devm_kasprintf(&ps_dev->hdev->dev, GFP_KERNEL, "%s:%s", in ps_led_register()
833 ps_dev->input_dev_name, led_info->color); in ps_led_register()
836 if (!led->name) in ps_led_register()
837 return -ENOMEM; in ps_led_register()
839 led->brightness = 0; in ps_led_register()
840 led->max_brightness = led_info->max_brightness; in ps_led_register()
841 led->flags = LED_CORE_SUSPENDRESUME; in ps_led_register()
842 led->brightness_get = led_info->brightness_get; in ps_led_register()
843 led->brightness_set_blocking = led_info->brightness_set; in ps_led_register()
844 led->blink_set = led_info->blink_set; in ps_led_register()
846 ret = devm_led_classdev_register(&ps_dev->hdev->dev, led); in ps_led_register()
848 hid_err(ps_dev->hdev, "Failed to register LED %s: %d\n", led_info->name, ret); in ps_led_register()
859 struct hid_device *hdev = ps_dev->hdev; in ps_lightbar_register()
864 mc_led_info = devm_kmalloc_array(&hdev->dev, 3, sizeof(*mc_led_info), in ps_lightbar_register()
867 return -ENOMEM; in ps_lightbar_register()
873 lightbar_mc_dev->subled_info = mc_led_info; in ps_lightbar_register()
874 lightbar_mc_dev->num_colors = 3; in ps_lightbar_register()
876 led_cdev = &lightbar_mc_dev->led_cdev; in ps_lightbar_register()
877 led_cdev->name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s:rgb:indicator", in ps_lightbar_register()
878 ps_dev->input_dev_name); in ps_lightbar_register()
879 if (!led_cdev->name) in ps_lightbar_register()
880 return -ENOMEM; in ps_lightbar_register()
881 led_cdev->brightness = 255; in ps_lightbar_register()
882 led_cdev->max_brightness = 255; in ps_lightbar_register()
883 led_cdev->brightness_set_blocking = brightness_set; in ps_lightbar_register()
885 ret = devm_led_classdev_multicolor_register(&hdev->dev, lightbar_mc_dev); in ps_lightbar_register()
904 __set_bit(INPUT_PROP_ACCELEROMETER, sensors->propbit); in ps_sensors_create()
905 __set_bit(EV_MSC, sensors->evbit); in ps_sensors_create()
906 __set_bit(MSC_TIMESTAMP, sensors->mscbit); in ps_sensors_create()
909 input_set_abs_params(sensors, ABS_X, -accel_range, accel_range, 16, 0); in ps_sensors_create()
910 input_set_abs_params(sensors, ABS_Y, -accel_range, accel_range, 16, 0); in ps_sensors_create()
911 input_set_abs_params(sensors, ABS_Z, -accel_range, accel_range, 16, 0); in ps_sensors_create()
917 input_set_abs_params(sensors, ABS_RX, -gyro_range, gyro_range, 16, 0); in ps_sensors_create()
918 input_set_abs_params(sensors, ABS_RY, -gyro_range, gyro_range, 16, 0); in ps_sensors_create()
919 input_set_abs_params(sensors, ABS_RZ, -gyro_range, gyro_range, 16, 0); in ps_sensors_create()
943 __set_bit(INPUT_PROP_BUTTONPAD, touchpad->propbit); in ps_touchpad_create()
945 input_set_abs_params(touchpad, ABS_MT_POSITION_X, 0, width - 1, 0, 0); in ps_touchpad_create()
946 input_set_abs_params(touchpad, ABS_MT_POSITION_Y, 0, height - 1, 0, 0); in ps_touchpad_create()
984 return sysfs_emit(buf, "0x%08x\n", ps_dev->fw_version); in firmware_version_show()
995 return sysfs_emit(buf, "0x%08x\n", ps_dev->hw_version); in hardware_version_show()
1009 struct hid_device *hdev = ds->base.hdev; in dualsense_get_calibration_data()
1025 return -ENOMEM; in dualsense_get_calibration_data()
1027 ret = ps_get_report(ds->base.hdev, DS_FEATURE_REPORT_CALIBRATION, buf, in dualsense_get_calibration_data()
1030 hid_err(ds->base.hdev, "Failed to retrieve DualSense calibration info: %d\n", ret); in dualsense_get_calibration_data()
1053 * Set gyroscope calibration and normalization parameters. in dualsense_get_calibration_data()
1054 * Data values will be normalized to 1/DS_GYRO_RES_PER_DEG_S degree/s. in dualsense_get_calibration_data()
1057 ds->gyro_calib_data[0].abs_code = ABS_RX; in dualsense_get_calibration_data()
1058 ds->gyro_calib_data[0].bias = 0; in dualsense_get_calibration_data()
1059 ds->gyro_calib_data[0].sens_numer = speed_2x * DS_GYRO_RES_PER_DEG_S; in dualsense_get_calibration_data()
1060 ds->gyro_calib_data[0].sens_denom = abs(gyro_pitch_plus - gyro_pitch_bias) + in dualsense_get_calibration_data()
1061 abs(gyro_pitch_minus - gyro_pitch_bias); in dualsense_get_calibration_data()
1063 ds->gyro_calib_data[1].abs_code = ABS_RY; in dualsense_get_calibration_data()
1064 ds->gyro_calib_data[1].bias = 0; in dualsense_get_calibration_data()
1065 ds->gyro_calib_data[1].sens_numer = speed_2x * DS_GYRO_RES_PER_DEG_S; in dualsense_get_calibration_data()
1066 ds->gyro_calib_data[1].sens_denom = abs(gyro_yaw_plus - gyro_yaw_bias) + in dualsense_get_calibration_data()
1067 abs(gyro_yaw_minus - gyro_yaw_bias); in dualsense_get_calibration_data()
1069 ds->gyro_calib_data[2].abs_code = ABS_RZ; in dualsense_get_calibration_data()
1070 ds->gyro_calib_data[2].bias = 0; in dualsense_get_calibration_data()
1071 ds->gyro_calib_data[2].sens_numer = speed_2x * DS_GYRO_RES_PER_DEG_S; in dualsense_get_calibration_data()
1072 ds->gyro_calib_data[2].sens_denom = abs(gyro_roll_plus - gyro_roll_bias) + in dualsense_get_calibration_data()
1073 abs(gyro_roll_minus - gyro_roll_bias); in dualsense_get_calibration_data()
1076 * Sanity check gyro calibration data. This is needed to prevent crashes in dualsense_get_calibration_data()
1078 * calibration data properly. in dualsense_get_calibration_data()
1080 for (i = 0; i < ARRAY_SIZE(ds->gyro_calib_data); i++) { in dualsense_get_calibration_data()
1081 if (ds->gyro_calib_data[i].sens_denom == 0) { in dualsense_get_calibration_data()
1083 "Invalid gyro calibration data for axis (%d), disabling calibration.", in dualsense_get_calibration_data()
1084 ds->gyro_calib_data[i].abs_code); in dualsense_get_calibration_data()
1085 ds->gyro_calib_data[i].bias = 0; in dualsense_get_calibration_data()
1086 ds->gyro_calib_data[i].sens_numer = DS_GYRO_RANGE; in dualsense_get_calibration_data()
1087 ds->gyro_calib_data[i].sens_denom = S16_MAX; in dualsense_get_calibration_data()
1092 * Set accelerometer calibration and normalization parameters. in dualsense_get_calibration_data()
1093 * Data values will be normalized to 1/DS_ACC_RES_PER_G g. in dualsense_get_calibration_data()
1095 range_2g = acc_x_plus - acc_x_minus; in dualsense_get_calibration_data()
1096 ds->accel_calib_data[0].abs_code = ABS_X; in dualsense_get_calibration_data()
1097 ds->accel_calib_data[0].bias = acc_x_plus - range_2g / 2; in dualsense_get_calibration_data()
1098 ds->accel_calib_data[0].sens_numer = 2 * DS_ACC_RES_PER_G; in dualsense_get_calibration_data()
1099 ds->accel_calib_data[0].sens_denom = range_2g; in dualsense_get_calibration_data()
1101 range_2g = acc_y_plus - acc_y_minus; in dualsense_get_calibration_data()
1102 ds->accel_calib_data[1].abs_code = ABS_Y; in dualsense_get_calibration_data()
1103 ds->accel_calib_data[1].bias = acc_y_plus - range_2g / 2; in dualsense_get_calibration_data()
1104 ds->accel_calib_data[1].sens_numer = 2 * DS_ACC_RES_PER_G; in dualsense_get_calibration_data()
1105 ds->accel_calib_data[1].sens_denom = range_2g; in dualsense_get_calibration_data()
1107 range_2g = acc_z_plus - acc_z_minus; in dualsense_get_calibration_data()
1108 ds->accel_calib_data[2].abs_code = ABS_Z; in dualsense_get_calibration_data()
1109 ds->accel_calib_data[2].bias = acc_z_plus - range_2g / 2; in dualsense_get_calibration_data()
1110 ds->accel_calib_data[2].sens_numer = 2 * DS_ACC_RES_PER_G; in dualsense_get_calibration_data()
1111 ds->accel_calib_data[2].sens_denom = range_2g; in dualsense_get_calibration_data()
1114 * Sanity check accelerometer calibration data. This is needed to prevent crashes in dualsense_get_calibration_data()
1115 * during report handling of virtual, clone or broken devices not implementing calibration in dualsense_get_calibration_data()
1116 * data properly. in dualsense_get_calibration_data()
1118 for (i = 0; i < ARRAY_SIZE(ds->accel_calib_data); i++) { in dualsense_get_calibration_data()
1119 if (ds->accel_calib_data[i].sens_denom == 0) { in dualsense_get_calibration_data()
1121 "Invalid accelerometer calibration data for axis (%d), disabling calibration.", in dualsense_get_calibration_data()
1122 ds->accel_calib_data[i].abs_code); in dualsense_get_calibration_data()
1123 ds->accel_calib_data[i].bias = 0; in dualsense_get_calibration_data()
1124 ds->accel_calib_data[i].sens_numer = DS_ACC_RANGE; in dualsense_get_calibration_data()
1125 ds->accel_calib_data[i].sens_denom = S16_MAX; in dualsense_get_calibration_data()
1141 return -ENOMEM; in dualsense_get_firmware_info()
1143 ret = ps_get_report(ds->base.hdev, DS_FEATURE_REPORT_FIRMWARE_INFO, buf, in dualsense_get_firmware_info()
1146 hid_err(ds->base.hdev, "Failed to retrieve DualSense firmware info: %d\n", ret); in dualsense_get_firmware_info()
1150 ds->base.hw_version = get_unaligned_le32(&buf[24]); in dualsense_get_firmware_info()
1151 ds->base.fw_version = get_unaligned_le32(&buf[28]); in dualsense_get_firmware_info()
1160 ds->update_version = get_unaligned_le16(&buf[44]); in dualsense_get_firmware_info()
1174 return -ENOMEM; in dualsense_get_mac_address()
1176 ret = ps_get_report(ds->base.hdev, DS_FEATURE_REPORT_PAIRING_INFO, buf, in dualsense_get_mac_address()
1179 hid_err(ds->base.hdev, "Failed to retrieve DualSense pairing info: %d\n", ret); in dualsense_get_mac_address()
1183 memcpy(ds->base.mac_address, &buf[1], sizeof(ds->base.mac_address)); in dualsense_get_mac_address()
1198 red = mc_cdev->subled_info[0].brightness; in dualsense_lightbar_set_brightness()
1199 green = mc_cdev->subled_info[1].brightness; in dualsense_lightbar_set_brightness()
1200 blue = mc_cdev->subled_info[2].brightness; in dualsense_lightbar_set_brightness()
1208 struct hid_device *hdev = to_hid_device(led->dev->parent); in dualsense_player_led_get_brightness()
1211 return !!(ds->player_leds_state & BIT(led - ds->player_leds)); in dualsense_player_led_get_brightness()
1216 struct hid_device *hdev = to_hid_device(led->dev->parent); in dualsense_player_led_set_brightness()
1220 scoped_guard(spinlock_irqsave, &ds->base.lock) { in dualsense_player_led_set_brightness()
1221 led_index = led - ds->player_leds; in dualsense_player_led_set_brightness()
1223 ds->player_leds_state &= ~BIT(led_index); in dualsense_player_led_set_brightness()
1225 ds->player_leds_state |= BIT(led_index); in dualsense_player_led_set_brightness()
1227 ds->update_player_leds = true; in dualsense_player_led_set_brightness()
1238 struct hid_device *hdev = ds->base.hdev; in dualsense_init_output_report()
1240 if (hdev->bus == BUS_BLUETOOTH) { in dualsense_init_output_report()
1244 bt->report_id = DS_OUTPUT_REPORT_BT; in dualsense_init_output_report()
1245 bt->tag = DS_OUTPUT_TAG; /* Tag must be set. Exact meaning is unclear. */ in dualsense_init_output_report()
1248 * Highest 4-bit is a sequence number, which needs to be increased in dualsense_init_output_report()
1249 * every report. Lowest 4-bit is tag and can be zero for now. in dualsense_init_output_report()
1251 bt->seq_tag = FIELD_PREP(DS_OUTPUT_SEQ_NO, ds->output_seq) | in dualsense_init_output_report()
1253 if (++ds->output_seq == 16) in dualsense_init_output_report()
1254 ds->output_seq = 0; in dualsense_init_output_report()
1256 rp->data = buf; in dualsense_init_output_report()
1257 rp->len = sizeof(*bt); in dualsense_init_output_report()
1258 rp->bt = bt; in dualsense_init_output_report()
1259 rp->usb = NULL; in dualsense_init_output_report()
1260 rp->common = &bt->common; in dualsense_init_output_report()
1265 usb->report_id = DS_OUTPUT_REPORT_USB; in dualsense_init_output_report()
1267 rp->data = buf; in dualsense_init_output_report()
1268 rp->len = sizeof(*usb); in dualsense_init_output_report()
1269 rp->bt = NULL; in dualsense_init_output_report()
1270 rp->usb = usb; in dualsense_init_output_report()
1271 rp->common = &usb->common; in dualsense_init_output_report()
1278 scoped_guard(spinlock_irqsave, &ds->base.lock) in dualsense_schedule_work()
1279 if (ds->output_worker_initialized) in dualsense_schedule_work()
1280 schedule_work(&ds->output_worker); in dualsense_schedule_work()
1290 struct hid_device *hdev = ds->base.hdev; in dualsense_send_output_report()
1293 if (report->bt) { in dualsense_send_output_report()
1298 crc = ~crc32_le(crc, report->data, report->len - 4); in dualsense_send_output_report()
1300 report->bt->crc32 = cpu_to_le32(crc); in dualsense_send_output_report()
1303 hid_hw_output_report(hdev, report->data, report->len); in dualsense_send_output_report()
1312 dualsense_init_output_report(ds, &report, ds->output_report_dmabuf); in dualsense_output_worker()
1315 scoped_guard(spinlock_irqsave, &ds->base.lock) { in dualsense_output_worker()
1316 if (ds->update_rumble) { in dualsense_output_worker()
1318 common->valid_flag0 |= DS_OUTPUT_VALID_FLAG0_HAPTICS_SELECT; in dualsense_output_worker()
1319 if (ds->use_vibration_v2) in dualsense_output_worker()
1320 common->valid_flag2 |= DS_OUTPUT_VALID_FLAG2_COMPATIBLE_VIBRATION2; in dualsense_output_worker()
1322 common->valid_flag0 |= DS_OUTPUT_VALID_FLAG0_COMPATIBLE_VIBRATION; in dualsense_output_worker()
1323 common->motor_left = ds->motor_left; in dualsense_output_worker()
1324 common->motor_right = ds->motor_right; in dualsense_output_worker()
1325 ds->update_rumble = false; in dualsense_output_worker()
1328 if (ds->update_lightbar) { in dualsense_output_worker()
1329 common->valid_flag1 |= DS_OUTPUT_VALID_FLAG1_LIGHTBAR_CONTROL_ENABLE; in dualsense_output_worker()
1330 common->lightbar_red = ds->lightbar_red; in dualsense_output_worker()
1331 common->lightbar_green = ds->lightbar_green; in dualsense_output_worker()
1332 common->lightbar_blue = ds->lightbar_blue; in dualsense_output_worker()
1334 ds->update_lightbar = false; in dualsense_output_worker()
1337 if (ds->update_player_leds) { in dualsense_output_worker()
1338 common->valid_flag1 |= in dualsense_output_worker()
1340 common->player_leds = ds->player_leds_state; in dualsense_output_worker()
1342 ds->update_player_leds = false; in dualsense_output_worker()
1345 if (ds->plugged_state != ds->prev_plugged_state) { in dualsense_output_worker()
1346 u8 val = ds->plugged_state & DS_STATUS1_HP_DETECT; in dualsense_output_worker()
1348 if (val != (ds->prev_plugged_state & DS_STATUS1_HP_DETECT)) { in dualsense_output_worker()
1349 common->valid_flag0 = DS_OUTPUT_VALID_FLAG0_AUDIO_CONTROL_ENABLE; in dualsense_output_worker()
1351 * _--------> Output path setup in audio_flag0 in dualsense_output_worker()
1352 * / _------> Headphone (HP) Left channel sink in dualsense_output_worker()
1353 * | / _----> Headphone (HP) Right channel sink in dualsense_output_worker()
1354 * | | / _--> Internal Speaker (SP) sink in dualsense_output_worker()
1356 * | | | | L/R - Left/Right channel source in dualsense_output_worker()
1357 * 0 L-R X X - Unrouted (muted) channel source in dualsense_output_worker()
1358 * 1 L-L X in dualsense_output_worker()
1359 * 2 L-L R in dualsense_output_worker()
1360 * 3 X-X R in dualsense_output_worker()
1364 common->audio_control = 0; in dualsense_output_worker()
1367 common->audio_control = in dualsense_output_worker()
1374 common->valid_flag0 |= in dualsense_output_worker()
1376 common->speaker_volume = 0x64; in dualsense_output_worker()
1378 common->valid_flag1 = in dualsense_output_worker()
1380 common->audio_control2 = in dualsense_output_worker()
1385 input_report_switch(ds->jack, SW_HEADPHONE_INSERT, val); in dualsense_output_worker()
1388 val = ds->plugged_state & DS_STATUS1_MIC_DETECT; in dualsense_output_worker()
1389 if (val != (ds->prev_plugged_state & DS_STATUS1_MIC_DETECT)) in dualsense_output_worker()
1390 input_report_switch(ds->jack, SW_MICROPHONE_INSERT, val); in dualsense_output_worker()
1392 input_sync(ds->jack); in dualsense_output_worker()
1393 ds->prev_plugged_state = ds->plugged_state; in dualsense_output_worker()
1396 if (ds->update_mic_mute) { in dualsense_output_worker()
1397 common->valid_flag1 |= DS_OUTPUT_VALID_FLAG1_MIC_MUTE_LED_CONTROL_ENABLE; in dualsense_output_worker()
1398 common->mute_button_led = ds->mic_muted; in dualsense_output_worker()
1400 if (ds->mic_muted) { in dualsense_output_worker()
1402 common->valid_flag1 |= in dualsense_output_worker()
1404 common->power_save_control |= DS_OUTPUT_POWER_SAVE_CONTROL_MIC_MUTE; in dualsense_output_worker()
1407 common->valid_flag1 |= in dualsense_output_worker()
1409 common->power_save_control &= in dualsense_output_worker()
1413 ds->update_mic_mute = false; in dualsense_output_worker()
1421 u8 *data, int size) in dualsense_parse_report() argument
1423 struct hid_device *hdev = ps_dev->hdev; in dualsense_parse_report()
1437 if (hdev->bus == BUS_USB && report->id == DS_INPUT_REPORT_USB && in dualsense_parse_report()
1439 ds_report = (struct dualsense_input_report *)&data[1]; in dualsense_parse_report()
1440 } else if (hdev->bus == BUS_BLUETOOTH && report->id == DS_INPUT_REPORT_BT && in dualsense_parse_report()
1443 u32 report_crc = get_unaligned_le32(&data[size - 4]); in dualsense_parse_report()
1445 if (!ps_check_crc32(PS_INPUT_CRC32_SEED, data, size - 4, report_crc)) { in dualsense_parse_report()
1447 return -EILSEQ; in dualsense_parse_report()
1450 ds_report = (struct dualsense_input_report *)&data[2]; in dualsense_parse_report()
1452 hid_err(hdev, "Unhandled reportID=%d\n", report->id); in dualsense_parse_report()
1453 return -1; in dualsense_parse_report()
1456 input_report_abs(ds->gamepad, ABS_X, ds_report->x); in dualsense_parse_report()
1457 input_report_abs(ds->gamepad, ABS_Y, ds_report->y); in dualsense_parse_report()
1458 input_report_abs(ds->gamepad, ABS_RX, ds_report->rx); in dualsense_parse_report()
1459 input_report_abs(ds->gamepad, ABS_RY, ds_report->ry); in dualsense_parse_report()
1460 input_report_abs(ds->gamepad, ABS_Z, ds_report->z); in dualsense_parse_report()
1461 input_report_abs(ds->gamepad, ABS_RZ, ds_report->rz); in dualsense_parse_report()
1463 value = ds_report->buttons[0] & DS_BUTTONS0_HAT_SWITCH; in dualsense_parse_report()
1466 input_report_abs(ds->gamepad, ABS_HAT0X, ps_gamepad_hat_mapping[value].x); in dualsense_parse_report()
1467 input_report_abs(ds->gamepad, ABS_HAT0Y, ps_gamepad_hat_mapping[value].y); in dualsense_parse_report()
1469 input_report_key(ds->gamepad, BTN_WEST, ds_report->buttons[0] & DS_BUTTONS0_SQUARE); in dualsense_parse_report()
1470 input_report_key(ds->gamepad, BTN_SOUTH, ds_report->buttons[0] & DS_BUTTONS0_CROSS); in dualsense_parse_report()
1471 input_report_key(ds->gamepad, BTN_EAST, ds_report->buttons[0] & DS_BUTTONS0_CIRCLE); in dualsense_parse_report()
1472 input_report_key(ds->gamepad, BTN_NORTH, ds_report->buttons[0] & DS_BUTTONS0_TRIANGLE); in dualsense_parse_report()
1473 input_report_key(ds->gamepad, BTN_TL, ds_report->buttons[1] & DS_BUTTONS1_L1); in dualsense_parse_report()
1474 input_report_key(ds->gamepad, BTN_TR, ds_report->buttons[1] & DS_BUTTONS1_R1); in dualsense_parse_report()
1475 input_report_key(ds->gamepad, BTN_TL2, ds_report->buttons[1] & DS_BUTTONS1_L2); in dualsense_parse_report()
1476 input_report_key(ds->gamepad, BTN_TR2, ds_report->buttons[1] & DS_BUTTONS1_R2); in dualsense_parse_report()
1477 input_report_key(ds->gamepad, BTN_SELECT, ds_report->buttons[1] & DS_BUTTONS1_CREATE); in dualsense_parse_report()
1478 input_report_key(ds->gamepad, BTN_START, ds_report->buttons[1] & DS_BUTTONS1_OPTIONS); in dualsense_parse_report()
1479 input_report_key(ds->gamepad, BTN_THUMBL, ds_report->buttons[1] & DS_BUTTONS1_L3); in dualsense_parse_report()
1480 input_report_key(ds->gamepad, BTN_THUMBR, ds_report->buttons[1] & DS_BUTTONS1_R3); in dualsense_parse_report()
1481 input_report_key(ds->gamepad, BTN_MODE, ds_report->buttons[2] & DS_BUTTONS2_PS_HOME); in dualsense_parse_report()
1482 input_sync(ds->gamepad); in dualsense_parse_report()
1489 btn_mic_state = !!(ds_report->buttons[2] & DS_BUTTONS2_MIC_MUTE); in dualsense_parse_report()
1490 if (btn_mic_state && !ds->last_btn_mic_state) { in dualsense_parse_report()
1491 scoped_guard(spinlock_irqsave, &ps_dev->lock) { in dualsense_parse_report()
1492 ds->update_mic_mute = true; in dualsense_parse_report()
1493 ds->mic_muted = !ds->mic_muted; /* toggle */ in dualsense_parse_report()
1499 ds->last_btn_mic_state = btn_mic_state; in dualsense_parse_report()
1502 * Parse HP/MIC plugged state data for USB use case, since Bluetooth in dualsense_parse_report()
1505 if (hdev->bus == BUS_USB) { in dualsense_parse_report()
1506 value = ds_report->status[1] & DS_STATUS1_JACK_DETECT; in dualsense_parse_report()
1508 if (!ds->prev_plugged_state_valid) { in dualsense_parse_report()
1510 scoped_guard(spinlock_irqsave, &ps_dev->lock) { in dualsense_parse_report()
1511 ds->plugged_state = (~value) & DS_STATUS1_JACK_DETECT; in dualsense_parse_report()
1512 ds->prev_plugged_state_valid = true; in dualsense_parse_report()
1516 if (value != ds->plugged_state) { in dualsense_parse_report()
1517 scoped_guard(spinlock_irqsave, &ps_dev->lock) { in dualsense_parse_report()
1518 ds->prev_plugged_state = ds->plugged_state; in dualsense_parse_report()
1519 ds->plugged_state = value; in dualsense_parse_report()
1527 /* Parse and calibrate gyroscope data. */ in dualsense_parse_report()
1528 for (i = 0; i < ARRAY_SIZE(ds_report->gyro); i++) { in dualsense_parse_report()
1529 int raw_data = (short)le16_to_cpu(ds_report->gyro[i]); in dualsense_parse_report()
1530 int calib_data = mult_frac(ds->gyro_calib_data[i].sens_numer, in dualsense_parse_report()
1531 raw_data, ds->gyro_calib_data[i].sens_denom); in dualsense_parse_report()
1533 input_report_abs(ds->sensors, ds->gyro_calib_data[i].abs_code, calib_data); in dualsense_parse_report()
1536 /* Parse and calibrate accelerometer data. */ in dualsense_parse_report()
1537 for (i = 0; i < ARRAY_SIZE(ds_report->accel); i++) { in dualsense_parse_report()
1538 int raw_data = (short)le16_to_cpu(ds_report->accel[i]); in dualsense_parse_report()
1539 int calib_data = mult_frac(ds->accel_calib_data[i].sens_numer, in dualsense_parse_report()
1540 raw_data - ds->accel_calib_data[i].bias, in dualsense_parse_report()
1541 ds->accel_calib_data[i].sens_denom); in dualsense_parse_report()
1543 input_report_abs(ds->sensors, ds->accel_calib_data[i].abs_code, calib_data); in dualsense_parse_report()
1547 sensor_timestamp = le32_to_cpu(ds_report->sensor_timestamp); in dualsense_parse_report()
1548 if (!ds->sensor_timestamp_initialized) { in dualsense_parse_report()
1549 ds->sensor_timestamp_us = DIV_ROUND_CLOSEST(sensor_timestamp, 3); in dualsense_parse_report()
1550 ds->sensor_timestamp_initialized = true; in dualsense_parse_report()
1554 if (ds->prev_sensor_timestamp > sensor_timestamp) in dualsense_parse_report()
1555 delta = (U32_MAX - ds->prev_sensor_timestamp + sensor_timestamp + 1); in dualsense_parse_report()
1557 delta = sensor_timestamp - ds->prev_sensor_timestamp; in dualsense_parse_report()
1558 ds->sensor_timestamp_us += DIV_ROUND_CLOSEST(delta, 3); in dualsense_parse_report()
1560 ds->prev_sensor_timestamp = sensor_timestamp; in dualsense_parse_report()
1561 input_event(ds->sensors, EV_MSC, MSC_TIMESTAMP, ds->sensor_timestamp_us); in dualsense_parse_report()
1562 input_sync(ds->sensors); in dualsense_parse_report()
1564 for (i = 0; i < ARRAY_SIZE(ds_report->points); i++) { in dualsense_parse_report()
1565 struct dualsense_touch_point *point = &ds_report->points[i]; in dualsense_parse_report()
1566 bool active = (point->contact & DS_TOUCH_POINT_INACTIVE) ? false : true; in dualsense_parse_report()
1568 input_mt_slot(ds->touchpad, i); in dualsense_parse_report()
1569 input_mt_report_slot_state(ds->touchpad, MT_TOOL_FINGER, active); in dualsense_parse_report()
1572 input_report_abs(ds->touchpad, ABS_MT_POSITION_X, in dualsense_parse_report()
1573 DS_TOUCH_POINT_X(point->x_hi, point->x_lo)); in dualsense_parse_report()
1574 input_report_abs(ds->touchpad, ABS_MT_POSITION_Y, in dualsense_parse_report()
1575 DS_TOUCH_POINT_Y(point->y_hi, point->y_lo)); in dualsense_parse_report()
1578 input_mt_sync_frame(ds->touchpad); in dualsense_parse_report()
1579 input_report_key(ds->touchpad, BTN_LEFT, ds_report->buttons[2] & DS_BUTTONS2_TOUCHPAD); in dualsense_parse_report()
1580 input_sync(ds->touchpad); in dualsense_parse_report()
1582 battery_data = FIELD_GET(DS_STATUS0_BATTERY_CAPACITY, ds_report->status[0]); in dualsense_parse_report()
1583 charging_status = FIELD_GET(DS_STATUS0_CHARGING, ds_report->status[0]); in dualsense_parse_report()
1588 * Each unit of battery data corresponds to 10% in dualsense_parse_report()
1589 * 0 = 0-9%, 1 = 10-19%, .. and 10 = 100% in dualsense_parse_report()
1613 scoped_guard(spinlock_irqsave, &ps_dev->lock) { in dualsense_parse_report()
1614 ps_dev->battery_capacity = battery_capacity; in dualsense_parse_report()
1615 ps_dev->battery_status = battery_status; in dualsense_parse_report()
1621 static int dualsense_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) in dualsense_play_effect() argument
1626 if (effect->type != FF_RUMBLE) in dualsense_play_effect()
1629 scoped_guard(spinlock_irqsave, &ds->base.lock) { in dualsense_play_effect()
1630 ds->update_rumble = true; in dualsense_play_effect()
1631 ds->motor_left = effect->u.rumble.strong_magnitude / 256; in dualsense_play_effect()
1632 ds->motor_right = effect->u.rumble.weak_magnitude / 256; in dualsense_play_effect()
1643 scoped_guard(spinlock_irqsave, &ds->base.lock) in dualsense_remove()
1644 ds->output_worker_initialized = false; in dualsense_remove()
1646 cancel_work_sync(&ds->output_worker); in dualsense_remove()
1656 return -ENOMEM; in dualsense_reset_leds()
1666 report.common->valid_flag2 = DS_OUTPUT_VALID_FLAG2_LIGHTBAR_SETUP_CONTROL_ENABLE; in dualsense_reset_leds()
1667 report.common->lightbar_setup = DS_OUTPUT_LIGHTBAR_SETUP_LIGHT_OUT; /* Fade light out. */ in dualsense_reset_leds()
1676 scoped_guard(spinlock_irqsave, &ds->base.lock) { in dualsense_set_lightbar()
1677 ds->update_lightbar = true; in dualsense_set_lightbar()
1678 ds->lightbar_red = red; in dualsense_set_lightbar()
1679 ds->lightbar_green = green; in dualsense_set_lightbar()
1680 ds->lightbar_blue = blue; in dualsense_set_lightbar()
1691 * across the LEDs, so e.g. player 1 would be "--x--" with x being 'on'. in dualsense_set_player_leds()
1702 u8 player_id = ds->base.player_id % ARRAY_SIZE(player_ids); in dualsense_set_player_leds()
1704 ds->update_player_leds = true; in dualsense_set_player_leds()
1705 ds->player_leds_state = player_ids[player_id]; in dualsense_set_player_leds()
1729 ds = devm_kzalloc(&hdev->dev, sizeof(*ds), GFP_KERNEL); in dualsense_create()
1731 return ERR_PTR(-ENOMEM); in dualsense_create()
1735 * hid-generic vs hid-playstation axis and button mapping. in dualsense_create()
1737 hdev->version |= HID_PLAYSTATION_VERSION_PATCH; in dualsense_create()
1739 ps_dev = &ds->base; in dualsense_create()
1740 ps_dev->hdev = hdev; in dualsense_create()
1741 spin_lock_init(&ps_dev->lock); in dualsense_create()
1742 ps_dev->battery_capacity = 100; /* initial value until parse_report. */ in dualsense_create()
1743 ps_dev->battery_status = POWER_SUPPLY_STATUS_UNKNOWN; in dualsense_create()
1744 ps_dev->parse_report = dualsense_parse_report; in dualsense_create()
1745 ps_dev->remove = dualsense_remove; in dualsense_create()
1746 INIT_WORK(&ds->output_worker, dualsense_output_worker); in dualsense_create()
1747 ds->output_worker_initialized = true; in dualsense_create()
1751 ds->output_report_dmabuf = devm_kzalloc(&hdev->dev, max_output_report_size, GFP_KERNEL); in dualsense_create()
1752 if (!ds->output_report_dmabuf) in dualsense_create()
1753 return ERR_PTR(-ENOMEM); in dualsense_create()
1760 snprintf(hdev->uniq, sizeof(hdev->uniq), "%pMR", ds->base.mac_address); in dualsense_create()
1776 if (hdev->product == USB_DEVICE_ID_SONY_PS5_CONTROLLER) { in dualsense_create()
1778 ds->use_vibration_v2 = ds->update_version >= DS_FEATURE_VERSION(2, 21); in dualsense_create()
1779 } else if (hdev->product == USB_DEVICE_ID_SONY_PS5_CONTROLLER_2) { in dualsense_create()
1780 ds->use_vibration_v2 = true; in dualsense_create()
1789 hid_err(hdev, "Failed to get calibration data from DualSense\n"); in dualsense_create()
1793 ds->gamepad = ps_gamepad_create(hdev, dualsense_play_effect); in dualsense_create()
1794 if (IS_ERR(ds->gamepad)) { in dualsense_create()
1795 ret = PTR_ERR(ds->gamepad); in dualsense_create()
1799 ps_dev->input_dev_name = dev_name(&ds->gamepad->dev); in dualsense_create()
1801 ds->sensors = ps_sensors_create(hdev, DS_ACC_RANGE, DS_ACC_RES_PER_G, in dualsense_create()
1803 if (IS_ERR(ds->sensors)) { in dualsense_create()
1804 ret = PTR_ERR(ds->sensors); in dualsense_create()
1808 ds->touchpad = ps_touchpad_create(hdev, DS_TOUCHPAD_WIDTH, DS_TOUCHPAD_HEIGHT, 2); in dualsense_create()
1809 if (IS_ERR(ds->touchpad)) { in dualsense_create()
1810 ret = PTR_ERR(ds->touchpad); in dualsense_create()
1815 if (hdev->bus == BUS_USB) { in dualsense_create()
1816 ds->jack = ps_headset_jack_create(hdev); in dualsense_create()
1817 if (IS_ERR(ds->jack)) { in dualsense_create()
1818 ret = PTR_ERR(ds->jack); in dualsense_create()
1836 ret = ps_lightbar_register(ps_dev, &ds->lightbar, dualsense_lightbar_set_brightness); in dualsense_create()
1846 ret = ps_led_register(ps_dev, &ds->player_leds[i], led_info); in dualsense_create()
1865 ds->base.hw_version, ds->base.fw_version); in dualsense_create()
1867 return &ds->base; in dualsense_create()
1884 * dongle as disabled. We will re-enable the dongle if a new in dualshock4_dongle_calibration_work()
1888 hid_err(ds4->base.hdev, in dualshock4_dongle_calibration_work()
1889 "DualShock 4 USB dongle: calibration failed, disabling device\n"); in dualshock4_dongle_calibration_work()
1892 hid_info(ds4->base.hdev, "DualShock 4 USB dongle: calibration completed\n"); in dualshock4_dongle_calibration_work()
1896 scoped_guard(spinlock_irqsave, &ds4->base.lock) in dualshock4_dongle_calibration_work()
1897 ds4->dongle_state = dongle_state; in dualshock4_dongle_calibration_work()
1902 struct hid_device *hdev = ds4->base.hdev; in dualshock4_get_calibration_data()
1916 if (ds4->base.hdev->bus == BUS_USB) { in dualshock4_get_calibration_data()
1921 ret = -ENOMEM; in dualshock4_get_calibration_data()
1925 /* We should normally receive the feature report data we asked in dualshock4_get_calibration_data()
1929 * data for a different HID report, so retry a few times. in dualshock4_get_calibration_data()
1937 "Retrying DualShock 4 get calibration report (0x02) request\n"); in dualshock4_get_calibration_data()
1942 "Failed to retrieve DualShock4 calibration info: %d\n", in dualshock4_get_calibration_data()
1944 ret = -EILSEQ; in dualshock4_get_calibration_data()
1954 ret = -ENOMEM; in dualshock4_get_calibration_data()
1962 hid_warn(hdev, "Failed to retrieve DualShock4 calibration info: %d\n", ret); in dualshock4_get_calibration_data()
1968 /* Transfer succeeded - parse the calibration data received. */ in dualshock4_get_calibration_data()
1972 if (ds4->base.hdev->bus == BUS_USB) { in dualshock4_get_calibration_data()
2001 * Set gyroscope calibration and normalization parameters. in dualshock4_get_calibration_data()
2002 * Data values will be normalized to 1/DS4_GYRO_RES_PER_DEG_S degree/s. in dualshock4_get_calibration_data()
2005 ds4->gyro_calib_data[0].abs_code = ABS_RX; in dualshock4_get_calibration_data()
2006 ds4->gyro_calib_data[0].bias = 0; in dualshock4_get_calibration_data()
2007 ds4->gyro_calib_data[0].sens_numer = speed_2x * DS4_GYRO_RES_PER_DEG_S; in dualshock4_get_calibration_data()
2008 ds4->gyro_calib_data[0].sens_denom = abs(gyro_pitch_plus - gyro_pitch_bias) + in dualshock4_get_calibration_data()
2009 abs(gyro_pitch_minus - gyro_pitch_bias); in dualshock4_get_calibration_data()
2011 ds4->gyro_calib_data[1].abs_code = ABS_RY; in dualshock4_get_calibration_data()
2012 ds4->gyro_calib_data[1].bias = 0; in dualshock4_get_calibration_data()
2013 ds4->gyro_calib_data[1].sens_numer = speed_2x * DS4_GYRO_RES_PER_DEG_S; in dualshock4_get_calibration_data()
2014 ds4->gyro_calib_data[1].sens_denom = abs(gyro_yaw_plus - gyro_yaw_bias) + in dualshock4_get_calibration_data()
2015 abs(gyro_yaw_minus - gyro_yaw_bias); in dualshock4_get_calibration_data()
2017 ds4->gyro_calib_data[2].abs_code = ABS_RZ; in dualshock4_get_calibration_data()
2018 ds4->gyro_calib_data[2].bias = 0; in dualshock4_get_calibration_data()
2019 ds4->gyro_calib_data[2].sens_numer = speed_2x * DS4_GYRO_RES_PER_DEG_S; in dualshock4_get_calibration_data()
2020 ds4->gyro_calib_data[2].sens_denom = abs(gyro_roll_plus - gyro_roll_bias) + in dualshock4_get_calibration_data()
2021 abs(gyro_roll_minus - gyro_roll_bias); in dualshock4_get_calibration_data()
2024 * Set accelerometer calibration and normalization parameters. in dualshock4_get_calibration_data()
2025 * Data values will be normalized to 1/DS4_ACC_RES_PER_G g. in dualshock4_get_calibration_data()
2027 range_2g = acc_x_plus - acc_x_minus; in dualshock4_get_calibration_data()
2028 ds4->accel_calib_data[0].abs_code = ABS_X; in dualshock4_get_calibration_data()
2029 ds4->accel_calib_data[0].bias = acc_x_plus - range_2g / 2; in dualshock4_get_calibration_data()
2030 ds4->accel_calib_data[0].sens_numer = 2 * DS4_ACC_RES_PER_G; in dualshock4_get_calibration_data()
2031 ds4->accel_calib_data[0].sens_denom = range_2g; in dualshock4_get_calibration_data()
2033 range_2g = acc_y_plus - acc_y_minus; in dualshock4_get_calibration_data()
2034 ds4->accel_calib_data[1].abs_code = ABS_Y; in dualshock4_get_calibration_data()
2035 ds4->accel_calib_data[1].bias = acc_y_plus - range_2g / 2; in dualshock4_get_calibration_data()
2036 ds4->accel_calib_data[1].sens_numer = 2 * DS4_ACC_RES_PER_G; in dualshock4_get_calibration_data()
2037 ds4->accel_calib_data[1].sens_denom = range_2g; in dualshock4_get_calibration_data()
2039 range_2g = acc_z_plus - acc_z_minus; in dualshock4_get_calibration_data()
2040 ds4->accel_calib_data[2].abs_code = ABS_Z; in dualshock4_get_calibration_data()
2041 ds4->accel_calib_data[2].bias = acc_z_plus - range_2g / 2; in dualshock4_get_calibration_data()
2042 ds4->accel_calib_data[2].sens_numer = 2 * DS4_ACC_RES_PER_G; in dualshock4_get_calibration_data()
2043 ds4->accel_calib_data[2].sens_denom = range_2g; in dualshock4_get_calibration_data()
2047 * Sanity check gyro calibration data. This is needed to prevent crashes in dualshock4_get_calibration_data()
2049 * calibration data properly. in dualshock4_get_calibration_data()
2051 for (i = 0; i < ARRAY_SIZE(ds4->gyro_calib_data); i++) { in dualshock4_get_calibration_data()
2052 if (ds4->gyro_calib_data[i].sens_denom == 0) { in dualshock4_get_calibration_data()
2053 ds4->gyro_calib_data[i].abs_code = ABS_RX + i; in dualshock4_get_calibration_data()
2055 "Invalid gyro calibration data for axis (%d), disabling calibration.", in dualshock4_get_calibration_data()
2056 ds4->gyro_calib_data[i].abs_code); in dualshock4_get_calibration_data()
2057 ds4->gyro_calib_data[i].bias = 0; in dualshock4_get_calibration_data()
2058 ds4->gyro_calib_data[i].sens_numer = DS4_GYRO_RANGE; in dualshock4_get_calibration_data()
2059 ds4->gyro_calib_data[i].sens_denom = S16_MAX; in dualshock4_get_calibration_data()
2064 * Sanity check accelerometer calibration data. This is needed to prevent crashes in dualshock4_get_calibration_data()
2065 * during report handling of virtual, clone or broken devices not implementing calibration in dualshock4_get_calibration_data()
2066 * data properly. in dualshock4_get_calibration_data()
2068 for (i = 0; i < ARRAY_SIZE(ds4->accel_calib_data); i++) { in dualshock4_get_calibration_data()
2069 if (ds4->accel_calib_data[i].sens_denom == 0) { in dualshock4_get_calibration_data()
2070 ds4->accel_calib_data[i].abs_code = ABS_X + i; in dualshock4_get_calibration_data()
2072 "Invalid accelerometer calibration data for axis (%d), disabling calibration.", in dualshock4_get_calibration_data()
2073 ds4->accel_calib_data[i].abs_code); in dualshock4_get_calibration_data()
2074 ds4->accel_calib_data[i].bias = 0; in dualshock4_get_calibration_data()
2075 ds4->accel_calib_data[i].sens_numer = DS4_ACC_RANGE; in dualshock4_get_calibration_data()
2076 ds4->accel_calib_data[i].sens_denom = S16_MAX; in dualshock4_get_calibration_data()
2090 return -ENOMEM; in dualshock4_get_firmware_info()
2095 ret = ps_get_report(ds4->base.hdev, DS4_FEATURE_REPORT_FIRMWARE_INFO, buf, in dualshock4_get_firmware_info()
2098 hid_err(ds4->base.hdev, "Failed to retrieve DualShock4 firmware info: %d\n", ret); in dualshock4_get_firmware_info()
2102 ds4->base.hw_version = get_unaligned_le16(&buf[35]); in dualshock4_get_firmware_info()
2103 ds4->base.fw_version = get_unaligned_le16(&buf[41]); in dualshock4_get_firmware_info()
2112 struct hid_device *hdev = ds4->base.hdev; in dualshock4_get_mac_address()
2116 if (hdev->bus == BUS_USB) { in dualshock4_get_mac_address()
2119 return -ENOMEM; in dualshock4_get_mac_address()
2128 memcpy(ds4->base.mac_address, &buf[1], sizeof(ds4->base.mac_address)); in dualshock4_get_mac_address()
2131 if (strlen(hdev->uniq) != 17) in dualshock4_get_mac_address()
2132 return -EINVAL; in dualshock4_get_mac_address()
2134 ret = sscanf(hdev->uniq, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", in dualshock4_get_mac_address()
2135 &ds4->base.mac_address[5], &ds4->base.mac_address[4], in dualshock4_get_mac_address()
2136 &ds4->base.mac_address[3], &ds4->base.mac_address[2], in dualshock4_get_mac_address()
2137 &ds4->base.mac_address[1], &ds4->base.mac_address[0]); in dualshock4_get_mac_address()
2139 if (ret != sizeof(ds4->base.mac_address)) in dualshock4_get_mac_address()
2140 return -EINVAL; in dualshock4_get_mac_address()
2152 struct hid_device *hdev = to_hid_device(led->dev->parent); in dualshock4_led_get_brightness()
2156 led_index = led - ds4->lightbar_leds; in dualshock4_led_get_brightness()
2159 return ds4->lightbar_red; in dualshock4_led_get_brightness()
2161 return ds4->lightbar_green; in dualshock4_led_get_brightness()
2163 return ds4->lightbar_blue; in dualshock4_led_get_brightness()
2165 return ds4->lightbar_enabled; in dualshock4_led_get_brightness()
2168 return -1; in dualshock4_led_get_brightness()
2174 struct hid_device *hdev = to_hid_device(led->dev->parent); in dualshock4_led_set_blink()
2177 scoped_guard(spinlock_irqsave, &ds4->base.lock) { in dualshock4_led_set_blink()
2180 ds4->lightbar_blink_on = 50; in dualshock4_led_set_blink()
2181 ds4->lightbar_blink_off = 50; in dualshock4_led_set_blink()
2184 ds4->lightbar_blink_on = min_t(unsigned long, *delay_on / 10, in dualshock4_led_set_blink()
2186 ds4->lightbar_blink_off = min_t(unsigned long, *delay_off / 10, in dualshock4_led_set_blink()
2190 ds4->update_lightbar_blink = true; in dualshock4_led_set_blink()
2196 *delay_on = ds4->lightbar_blink_on * 10; in dualshock4_led_set_blink()
2197 *delay_off = ds4->lightbar_blink_off * 10; in dualshock4_led_set_blink()
2204 struct hid_device *hdev = to_hid_device(led->dev->parent); in dualshock4_led_set_brightness()
2208 scoped_guard(spinlock_irqsave, &ds4->base.lock) { in dualshock4_led_set_brightness()
2209 led_index = led - ds4->lightbar_leds; in dualshock4_led_set_brightness()
2212 ds4->lightbar_red = value; in dualshock4_led_set_brightness()
2215 ds4->lightbar_green = value; in dualshock4_led_set_brightness()
2218 ds4->lightbar_blue = value; in dualshock4_led_set_brightness()
2221 ds4->lightbar_enabled = !!value; in dualshock4_led_set_brightness()
2224 if (!ds4->lightbar_enabled) { in dualshock4_led_set_brightness()
2225 ds4->lightbar_blink_off = 0; in dualshock4_led_set_brightness()
2226 ds4->lightbar_blink_on = 0; in dualshock4_led_set_brightness()
2227 ds4->update_lightbar_blink = true; in dualshock4_led_set_brightness()
2231 ds4->update_lightbar = true; in dualshock4_led_set_brightness()
2242 struct hid_device *hdev = ds4->base.hdev; in dualshock4_init_output_report()
2244 if (hdev->bus == BUS_BLUETOOTH) { in dualshock4_init_output_report()
2248 bt->report_id = DS4_OUTPUT_REPORT_BT; in dualshock4_init_output_report()
2250 rp->data = buf; in dualshock4_init_output_report()
2251 rp->len = sizeof(*bt); in dualshock4_init_output_report()
2252 rp->bt = bt; in dualshock4_init_output_report()
2253 rp->usb = NULL; in dualshock4_init_output_report()
2254 rp->common = &bt->common; in dualshock4_init_output_report()
2259 usb->report_id = DS4_OUTPUT_REPORT_USB; in dualshock4_init_output_report()
2261 rp->data = buf; in dualshock4_init_output_report()
2262 rp->len = sizeof(*usb); in dualshock4_init_output_report()
2263 rp->bt = NULL; in dualshock4_init_output_report()
2264 rp->usb = usb; in dualshock4_init_output_report()
2265 rp->common = &usb->common; in dualshock4_init_output_report()
2275 dualshock4_init_output_report(ds4, &report, ds4->output_report_dmabuf); in dualshock4_output_worker()
2278 scoped_guard(spinlock_irqsave, &ds4->base.lock) { in dualshock4_output_worker()
2287 * ds4->valid_flag0 >= 0x03 in dualshock4_output_worker()
2289 * Hopefully this will maximise compatibility with third-party pads. in dualshock4_output_worker()
2294 if (ds4->update_rumble || ds4->update_lightbar) { in dualshock4_output_worker()
2295 ds4->update_rumble = true; /* 0x01 */ in dualshock4_output_worker()
2296 ds4->update_lightbar = true; /* 0x02 */ in dualshock4_output_worker()
2299 if (ds4->update_rumble) { in dualshock4_output_worker()
2301 common->valid_flag0 |= DS4_OUTPUT_VALID_FLAG0_MOTOR; in dualshock4_output_worker()
2302 common->motor_left = ds4->motor_left; in dualshock4_output_worker()
2303 common->motor_right = ds4->motor_right; in dualshock4_output_worker()
2304 ds4->update_rumble = false; in dualshock4_output_worker()
2307 if (ds4->update_lightbar) { in dualshock4_output_worker()
2308 common->valid_flag0 |= DS4_OUTPUT_VALID_FLAG0_LED; in dualshock4_output_worker()
2309 /* Compatible behavior with hid-sony, which used a dummy global LED to in dualshock4_output_worker()
2313 common->lightbar_red = ds4->lightbar_enabled ? ds4->lightbar_red : 0; in dualshock4_output_worker()
2314 common->lightbar_green = ds4->lightbar_enabled ? ds4->lightbar_green : 0; in dualshock4_output_worker()
2315 common->lightbar_blue = ds4->lightbar_enabled ? ds4->lightbar_blue : 0; in dualshock4_output_worker()
2316 ds4->update_lightbar = false; in dualshock4_output_worker()
2319 if (ds4->update_lightbar_blink) { in dualshock4_output_worker()
2320 common->valid_flag0 |= DS4_OUTPUT_VALID_FLAG0_LED_BLINK; in dualshock4_output_worker()
2321 common->lightbar_blink_on = ds4->lightbar_blink_on; in dualshock4_output_worker()
2322 common->lightbar_blink_off = ds4->lightbar_blink_off; in dualshock4_output_worker()
2323 ds4->update_lightbar_blink = false; in dualshock4_output_worker()
2333 * there is HID data as well as CRC. in dualshock4_output_worker()
2335 report.bt->hw_control = DS4_OUTPUT_HWCTL_HID | DS4_OUTPUT_HWCTL_CRC32; in dualshock4_output_worker()
2337 if (ds4->update_bt_poll_interval) { in dualshock4_output_worker()
2338 report.bt->hw_control |= ds4->bt_poll_interval; in dualshock4_output_worker()
2339 ds4->update_bt_poll_interval = false; in dualshock4_output_worker()
2343 crc = ~crc32_le(crc, report.data, report.len - 4); in dualshock4_output_worker()
2345 report.bt->crc32 = cpu_to_le32(crc); in dualshock4_output_worker()
2348 hid_hw_output_report(ds4->base.hdev, report.data, report.len); in dualshock4_output_worker()
2352 u8 *data, int size) in dualshock4_parse_report() argument
2354 struct hid_device *hdev = ps_dev->hdev; in dualshock4_parse_report()
2368 if (hdev->bus == BUS_USB && report->id == DS4_INPUT_REPORT_USB && in dualshock4_parse_report()
2371 (struct dualshock4_input_report_usb *)data; in dualshock4_parse_report()
2373 ds4_report = &usb->common; in dualshock4_parse_report()
2374 num_touch_reports = usb->num_touch_reports; in dualshock4_parse_report()
2375 touch_reports = usb->touch_reports; in dualshock4_parse_report()
2376 } else if (hdev->bus == BUS_BLUETOOTH && report->id == DS4_INPUT_REPORT_BT && in dualshock4_parse_report()
2378 struct dualshock4_input_report_bt *bt = (struct dualshock4_input_report_bt *)data; in dualshock4_parse_report()
2379 u32 report_crc = get_unaligned_le32(&bt->crc32); in dualshock4_parse_report()
2382 if (!ps_check_crc32(PS_INPUT_CRC32_SEED, data, size - 4, report_crc)) { in dualshock4_parse_report()
2384 return -EILSEQ; in dualshock4_parse_report()
2387 ds4_report = &bt->common; in dualshock4_parse_report()
2388 num_touch_reports = bt->num_touch_reports; in dualshock4_parse_report()
2389 touch_reports = bt->touch_reports; in dualshock4_parse_report()
2390 } else if (hdev->bus == BUS_BLUETOOTH && in dualshock4_parse_report()
2391 report->id == DS4_INPUT_REPORT_BT_MINIMAL && in dualshock4_parse_report()
2393 /* Some third-party pads never switch to the full 0x11 report. in dualshock4_parse_report()
2400 ds4_report = (struct dualshock4_input_report_common *)&data[1]; in dualshock4_parse_report()
2403 hid_err(hdev, "Unhandled reportID=%d\n", report->id); in dualshock4_parse_report()
2404 return -1; in dualshock4_parse_report()
2407 input_report_abs(ds4->gamepad, ABS_X, ds4_report->x); in dualshock4_parse_report()
2408 input_report_abs(ds4->gamepad, ABS_Y, ds4_report->y); in dualshock4_parse_report()
2409 input_report_abs(ds4->gamepad, ABS_RX, ds4_report->rx); in dualshock4_parse_report()
2410 input_report_abs(ds4->gamepad, ABS_RY, ds4_report->ry); in dualshock4_parse_report()
2411 input_report_abs(ds4->gamepad, ABS_Z, ds4_report->z); in dualshock4_parse_report()
2412 input_report_abs(ds4->gamepad, ABS_RZ, ds4_report->rz); in dualshock4_parse_report()
2414 value = ds4_report->buttons[0] & DS_BUTTONS0_HAT_SWITCH; in dualshock4_parse_report()
2417 input_report_abs(ds4->gamepad, ABS_HAT0X, ps_gamepad_hat_mapping[value].x); in dualshock4_parse_report()
2418 input_report_abs(ds4->gamepad, ABS_HAT0Y, ps_gamepad_hat_mapping[value].y); in dualshock4_parse_report()
2420 input_report_key(ds4->gamepad, BTN_WEST, ds4_report->buttons[0] & DS_BUTTONS0_SQUARE); in dualshock4_parse_report()
2421 input_report_key(ds4->gamepad, BTN_SOUTH, ds4_report->buttons[0] & DS_BUTTONS0_CROSS); in dualshock4_parse_report()
2422 input_report_key(ds4->gamepad, BTN_EAST, ds4_report->buttons[0] & DS_BUTTONS0_CIRCLE); in dualshock4_parse_report()
2423 input_report_key(ds4->gamepad, BTN_NORTH, ds4_report->buttons[0] & DS_BUTTONS0_TRIANGLE); in dualshock4_parse_report()
2424 input_report_key(ds4->gamepad, BTN_TL, ds4_report->buttons[1] & DS_BUTTONS1_L1); in dualshock4_parse_report()
2425 input_report_key(ds4->gamepad, BTN_TR, ds4_report->buttons[1] & DS_BUTTONS1_R1); in dualshock4_parse_report()
2426 input_report_key(ds4->gamepad, BTN_TL2, ds4_report->buttons[1] & DS_BUTTONS1_L2); in dualshock4_parse_report()
2427 input_report_key(ds4->gamepad, BTN_TR2, ds4_report->buttons[1] & DS_BUTTONS1_R2); in dualshock4_parse_report()
2428 input_report_key(ds4->gamepad, BTN_SELECT, ds4_report->buttons[1] & DS_BUTTONS1_CREATE); in dualshock4_parse_report()
2429 input_report_key(ds4->gamepad, BTN_START, ds4_report->buttons[1] & DS_BUTTONS1_OPTIONS); in dualshock4_parse_report()
2430 input_report_key(ds4->gamepad, BTN_THUMBL, ds4_report->buttons[1] & DS_BUTTONS1_L3); in dualshock4_parse_report()
2431 input_report_key(ds4->gamepad, BTN_THUMBR, ds4_report->buttons[1] & DS_BUTTONS1_R3); in dualshock4_parse_report()
2432 input_report_key(ds4->gamepad, BTN_MODE, ds4_report->buttons[2] & DS_BUTTONS2_PS_HOME); in dualshock4_parse_report()
2433 input_sync(ds4->gamepad); in dualshock4_parse_report()
2438 /* Parse and calibrate gyroscope data. */ in dualshock4_parse_report()
2439 for (i = 0; i < ARRAY_SIZE(ds4_report->gyro); i++) { in dualshock4_parse_report()
2440 int raw_data = (short)le16_to_cpu(ds4_report->gyro[i]); in dualshock4_parse_report()
2441 int calib_data = mult_frac(ds4->gyro_calib_data[i].sens_numer, in dualshock4_parse_report()
2442 raw_data, ds4->gyro_calib_data[i].sens_denom); in dualshock4_parse_report()
2444 input_report_abs(ds4->sensors, ds4->gyro_calib_data[i].abs_code, calib_data); in dualshock4_parse_report()
2447 /* Parse and calibrate accelerometer data. */ in dualshock4_parse_report()
2448 for (i = 0; i < ARRAY_SIZE(ds4_report->accel); i++) { in dualshock4_parse_report()
2449 int raw_data = (short)le16_to_cpu(ds4_report->accel[i]); in dualshock4_parse_report()
2450 int calib_data = mult_frac(ds4->accel_calib_data[i].sens_numer, in dualshock4_parse_report()
2451 raw_data - ds4->accel_calib_data[i].bias, in dualshock4_parse_report()
2452 ds4->accel_calib_data[i].sens_denom); in dualshock4_parse_report()
2454 input_report_abs(ds4->sensors, ds4->accel_calib_data[i].abs_code, calib_data); in dualshock4_parse_report()
2458 sensor_timestamp = le16_to_cpu(ds4_report->sensor_timestamp); in dualshock4_parse_report()
2459 if (!ds4->sensor_timestamp_initialized) { in dualshock4_parse_report()
2460 ds4->sensor_timestamp_us = DIV_ROUND_CLOSEST(sensor_timestamp * 16, 3); in dualshock4_parse_report()
2461 ds4->sensor_timestamp_initialized = true; in dualshock4_parse_report()
2465 if (ds4->prev_sensor_timestamp > sensor_timestamp) in dualshock4_parse_report()
2466 delta = (U16_MAX - ds4->prev_sensor_timestamp + sensor_timestamp + 1); in dualshock4_parse_report()
2468 delta = sensor_timestamp - ds4->prev_sensor_timestamp; in dualshock4_parse_report()
2469 ds4->sensor_timestamp_us += DIV_ROUND_CLOSEST(delta * 16, 3); in dualshock4_parse_report()
2471 ds4->prev_sensor_timestamp = sensor_timestamp; in dualshock4_parse_report()
2472 input_event(ds4->sensors, EV_MSC, MSC_TIMESTAMP, ds4->sensor_timestamp_us); in dualshock4_parse_report()
2473 input_sync(ds4->sensors); in dualshock4_parse_report()
2478 for (j = 0; j < ARRAY_SIZE(touch_report->points); j++) { in dualshock4_parse_report()
2479 struct dualshock4_touch_point *point = &touch_report->points[j]; in dualshock4_parse_report()
2480 bool active = (point->contact & DS4_TOUCH_POINT_INACTIVE) ? false : true; in dualshock4_parse_report()
2482 input_mt_slot(ds4->touchpad, j); in dualshock4_parse_report()
2483 input_mt_report_slot_state(ds4->touchpad, MT_TOOL_FINGER, active); in dualshock4_parse_report()
2486 input_report_abs(ds4->touchpad, ABS_MT_POSITION_X, in dualshock4_parse_report()
2487 DS4_TOUCH_POINT_X(point->x_hi, point->x_lo)); in dualshock4_parse_report()
2488 input_report_abs(ds4->touchpad, ABS_MT_POSITION_Y, in dualshock4_parse_report()
2489 DS4_TOUCH_POINT_Y(point->y_hi, point->y_lo)); in dualshock4_parse_report()
2492 input_mt_sync_frame(ds4->touchpad); in dualshock4_parse_report()
2493 input_sync(ds4->touchpad); in dualshock4_parse_report()
2495 input_report_key(ds4->touchpad, BTN_LEFT, ds4_report->buttons[2] & DS_BUTTONS2_TOUCHPAD); in dualshock4_parse_report()
2498 * Interpretation of the battery_capacity data depends on the cable state. in dualshock4_parse_report()
2500 * - 0:10: percentage in units of 10%. in dualshock4_parse_report()
2502 * - 0-10: percentage in units of 10%. in dualshock4_parse_report()
2503 * - 11: battery is full in dualshock4_parse_report()
2504 * - 14: not charging due to Voltage or temperature error in dualshock4_parse_report()
2505 * - 15: charge error in dualshock4_parse_report()
2507 if (ds4_report->status[0] & DS4_STATUS0_CABLE_STATE) { in dualshock4_parse_report()
2508 u8 battery_data = ds4_report->status[0] & DS4_STATUS0_BATTERY_CAPACITY; in dualshock4_parse_report()
2511 /* Take the mid-point for each battery capacity value, in dualshock4_parse_report()
2512 * because on the hardware side 0 = 0-9%, 1=10-19%, etc. in dualshock4_parse_report()
2529 u8 battery_data = ds4_report->status[0] & DS4_STATUS0_BATTERY_CAPACITY; in dualshock4_parse_report()
2539 scoped_guard(spinlock_irqsave, &ps_dev->lock) { in dualshock4_parse_report()
2540 ps_dev->battery_capacity = battery_capacity; in dualshock4_parse_report()
2541 ps_dev->battery_status = battery_status; in dualshock4_parse_report()
2548 u8 *data, int size) in dualshock4_dongle_parse_report() argument
2553 /* The dongle reports data using the main USB report (0x1) no matter whether a controller in dualshock4_dongle_parse_report()
2558 if (data[0] == DS4_INPUT_REPORT_USB && size == DS4_INPUT_REPORT_USB_SIZE) { in dualshock4_dongle_parse_report()
2560 (struct dualshock4_input_report_common *)&data[1]; in dualshock4_dongle_parse_report()
2562 connected = ds4_report->status[1] & DS4_STATUS1_DONGLE_STATE ? false : true; in dualshock4_dongle_parse_report()
2564 if (ds4->dongle_state == DONGLE_DISCONNECTED && connected) { in dualshock4_dongle_parse_report()
2565 hid_info(ps_dev->hdev, "DualShock 4 USB dongle: controller connected\n"); in dualshock4_dongle_parse_report()
2569 scoped_guard(spinlock_irqsave, &ps_dev->lock) in dualshock4_dongle_parse_report()
2570 ds4->dongle_state = DONGLE_CALIBRATING; in dualshock4_dongle_parse_report()
2572 schedule_work(&ds4->dongle_hotplug_worker); in dualshock4_dongle_parse_report()
2575 * calibration data, but let hidraw have it anyway. in dualshock4_dongle_parse_report()
2578 } else if ((ds4->dongle_state == DONGLE_CONNECTED || in dualshock4_dongle_parse_report()
2579 ds4->dongle_state == DONGLE_DISABLED) && !connected) { in dualshock4_dongle_parse_report()
2580 hid_info(ps_dev->hdev, "DualShock 4 USB dongle: controller disconnected\n"); in dualshock4_dongle_parse_report()
2582 scoped_guard(spinlock_irqsave, &ps_dev->lock) in dualshock4_dongle_parse_report()
2583 ds4->dongle_state = DONGLE_DISCONNECTED; in dualshock4_dongle_parse_report()
2587 } else if (ds4->dongle_state == DONGLE_CALIBRATING || in dualshock4_dongle_parse_report()
2588 ds4->dongle_state == DONGLE_DISABLED || in dualshock4_dongle_parse_report()
2589 ds4->dongle_state == DONGLE_DISCONNECTED) { in dualshock4_dongle_parse_report()
2596 return dualshock4_parse_report(ps_dev, report, data, size); in dualshock4_dongle_parse_report()
2601 static int dualshock4_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) in dualshock4_play_effect() argument
2606 if (effect->type != FF_RUMBLE) in dualshock4_play_effect()
2609 scoped_guard(spinlock_irqsave, &ds4->base.lock) { in dualshock4_play_effect()
2610 ds4->update_rumble = true; in dualshock4_play_effect()
2611 ds4->motor_left = effect->u.rumble.strong_magnitude / 256; in dualshock4_play_effect()
2612 ds4->motor_right = effect->u.rumble.weak_magnitude / 256; in dualshock4_play_effect()
2623 scoped_guard(spinlock_irqsave, &ds4->base.lock) in dualshock4_remove()
2624 ds4->output_worker_initialized = false; in dualshock4_remove()
2626 cancel_work_sync(&ds4->output_worker); in dualshock4_remove()
2628 if (ps_dev->hdev->product == USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE) in dualshock4_remove()
2629 cancel_work_sync(&ds4->dongle_hotplug_worker); in dualshock4_remove()
2635 scoped_guard(spinlock_irqsave, &ds4->base.lock) in dualshock4_schedule_work()
2636 if (ds4->output_worker_initialized) in dualshock4_schedule_work()
2637 schedule_work(&ds4->output_worker); in dualshock4_schedule_work()
2642 ds4->bt_poll_interval = interval; in dualshock4_set_bt_poll_interval()
2643 ds4->update_bt_poll_interval = true; in dualshock4_set_bt_poll_interval()
2660 u8 player_id = ds4->base.player_id % ARRAY_SIZE(player_colors); in dualshock4_set_default_lightbar_colors()
2662 ds4->lightbar_enabled = true; in dualshock4_set_default_lightbar_colors()
2663 ds4->lightbar_red = player_colors[player_id][0]; in dualshock4_set_default_lightbar_colors()
2664 ds4->lightbar_green = player_colors[player_id][1]; in dualshock4_set_default_lightbar_colors()
2665 ds4->lightbar_blue = player_colors[player_id][2]; in dualshock4_set_default_lightbar_colors()
2667 ds4->update_lightbar = true; in dualshock4_set_default_lightbar_colors()
2678 /* The DualShock4 has an RGB lightbar, which the original hid-sony driver in dualshock4_create()
2680 * Ideally this should have used the multi-color LED class, which didn't exist in dualshock4_create()
2698 ds4 = devm_kzalloc(&hdev->dev, sizeof(*ds4), GFP_KERNEL); in dualshock4_create()
2700 return ERR_PTR(-ENOMEM); in dualshock4_create()
2704 * hid-generic vs hid-playstation axis and button mapping. in dualshock4_create()
2706 hdev->version |= HID_PLAYSTATION_VERSION_PATCH; in dualshock4_create()
2708 ps_dev = &ds4->base; in dualshock4_create()
2709 ps_dev->hdev = hdev; in dualshock4_create()
2710 spin_lock_init(&ps_dev->lock); in dualshock4_create()
2711 ps_dev->battery_capacity = 100; /* initial value until parse_report. */ in dualshock4_create()
2712 ps_dev->battery_status = POWER_SUPPLY_STATUS_UNKNOWN; in dualshock4_create()
2713 ps_dev->parse_report = dualshock4_parse_report; in dualshock4_create()
2714 ps_dev->remove = dualshock4_remove; in dualshock4_create()
2715 INIT_WORK(&ds4->output_worker, dualshock4_output_worker); in dualshock4_create()
2716 ds4->output_worker_initialized = true; in dualshock4_create()
2720 ds4->output_report_dmabuf = devm_kzalloc(&hdev->dev, max_output_report_size, GFP_KERNEL); in dualshock4_create()
2721 if (!ds4->output_report_dmabuf) in dualshock4_create()
2722 return ERR_PTR(-ENOMEM); in dualshock4_create()
2724 if (hdev->product == USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE) { in dualshock4_create()
2725 ds4->dongle_state = DONGLE_DISCONNECTED; in dualshock4_create()
2726 INIT_WORK(&ds4->dongle_hotplug_worker, dualshock4_dongle_calibration_work); in dualshock4_create()
2729 ps_dev->parse_report = dualshock4_dongle_parse_report; in dualshock4_create()
2737 snprintf(hdev->uniq, sizeof(hdev->uniq), "%pMR", ds4->base.mac_address); in dualshock4_create()
2742 hid_warn(hdev, "HW/FW version data in sysfs will be invalid.\n"); in dualshock4_create()
2751 hid_warn(hdev, "Failed to get calibration data from DualShock4\n"); in dualshock4_create()
2755 ds4->gamepad = ps_gamepad_create(hdev, dualshock4_play_effect); in dualshock4_create()
2756 if (IS_ERR(ds4->gamepad)) { in dualshock4_create()
2757 ret = PTR_ERR(ds4->gamepad); in dualshock4_create()
2762 ps_dev->input_dev_name = dev_name(&ds4->gamepad->dev); in dualshock4_create()
2764 ds4->sensors = ps_sensors_create(hdev, DS4_ACC_RANGE, DS4_ACC_RES_PER_G, in dualshock4_create()
2766 if (IS_ERR(ds4->sensors)) { in dualshock4_create()
2767 ret = PTR_ERR(ds4->sensors); in dualshock4_create()
2771 ds4->touchpad = ps_touchpad_create(hdev, DS4_TOUCHPAD_WIDTH, DS4_TOUCHPAD_HEIGHT, 2); in dualshock4_create()
2772 if (IS_ERR(ds4->touchpad)) { in dualshock4_create()
2773 ret = PTR_ERR(ds4->touchpad); in dualshock4_create()
2784 ret = ps_led_register(ps_dev, &ds4->lightbar_leds[i], led_info); in dualshock4_create()
2804 ds4->base.hw_version, ds4->base.fw_version); in dualshock4_create()
2805 return &ds4->base; in dualshock4_create()
2813 u8 *data, int size) in ps_raw_event() argument
2817 if (dev && dev->parse_report) in ps_raw_event()
2818 return dev->parse_report(dev, report, data, size); in ps_raw_event()
2846 if (id->driver_data == PS_TYPE_PS4_DUALSHOCK4) { in ps_probe()
2853 } else if (id->driver_data == PS_TYPE_PS5_DUALSENSE) { in ps_probe()
2878 if (dev->remove) in ps_remove()
2879 dev->remove(dev); in ps_remove()