#include <linux/bits.h>
#include <linux/crc32.h>
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/idr.h>
#include <linux/input/mt.h>
#include <linux/leds.h>
#include <linux/led-class-multicolor.h>
#include <linux/module.h>
#include <asm/unaligned.h>
#include "hid-ids.h"
static DEFINE_MUTEX(ps_devices_lock);
static LIST_HEAD(ps_devices_list);
static DEFINE_IDA(ps_player_id_allocator);
#define HID_PLAYSTATION_VERSION_PATCH …
enum PS_TYPE { … };
struct ps_device { … };
struct ps_calibration_data { … };
struct ps_led_info { … };
#define PS_INPUT_CRC32_SEED …
#define PS_OUTPUT_CRC32_SEED …
#define PS_FEATURE_CRC32_SEED …
#define DS_INPUT_REPORT_USB …
#define DS_INPUT_REPORT_USB_SIZE …
#define DS_INPUT_REPORT_BT …
#define DS_INPUT_REPORT_BT_SIZE …
#define DS_OUTPUT_REPORT_USB …
#define DS_OUTPUT_REPORT_USB_SIZE …
#define DS_OUTPUT_REPORT_BT …
#define DS_OUTPUT_REPORT_BT_SIZE …
#define DS_FEATURE_REPORT_CALIBRATION …
#define DS_FEATURE_REPORT_CALIBRATION_SIZE …
#define DS_FEATURE_REPORT_PAIRING_INFO …
#define DS_FEATURE_REPORT_PAIRING_INFO_SIZE …
#define DS_FEATURE_REPORT_FIRMWARE_INFO …
#define DS_FEATURE_REPORT_FIRMWARE_INFO_SIZE …
#define DS_BUTTONS0_HAT_SWITCH …
#define DS_BUTTONS0_SQUARE …
#define DS_BUTTONS0_CROSS …
#define DS_BUTTONS0_CIRCLE …
#define DS_BUTTONS0_TRIANGLE …
#define DS_BUTTONS1_L1 …
#define DS_BUTTONS1_R1 …
#define DS_BUTTONS1_L2 …
#define DS_BUTTONS1_R2 …
#define DS_BUTTONS1_CREATE …
#define DS_BUTTONS1_OPTIONS …
#define DS_BUTTONS1_L3 …
#define DS_BUTTONS1_R3 …
#define DS_BUTTONS2_PS_HOME …
#define DS_BUTTONS2_TOUCHPAD …
#define DS_BUTTONS2_MIC_MUTE …
#define DS_STATUS_BATTERY_CAPACITY …
#define DS_STATUS_CHARGING …
#define DS_STATUS_CHARGING_SHIFT …
#define DS_FEATURE_VERSION(major, minor) …
#define DS_TOUCH_POINT_INACTIVE …
#define DS_OUTPUT_TAG …
#define DS_OUTPUT_VALID_FLAG0_COMPATIBLE_VIBRATION …
#define DS_OUTPUT_VALID_FLAG0_HAPTICS_SELECT …
#define DS_OUTPUT_VALID_FLAG1_MIC_MUTE_LED_CONTROL_ENABLE …
#define DS_OUTPUT_VALID_FLAG1_POWER_SAVE_CONTROL_ENABLE …
#define DS_OUTPUT_VALID_FLAG1_LIGHTBAR_CONTROL_ENABLE …
#define DS_OUTPUT_VALID_FLAG1_RELEASE_LEDS …
#define DS_OUTPUT_VALID_FLAG1_PLAYER_INDICATOR_CONTROL_ENABLE …
#define DS_OUTPUT_VALID_FLAG2_LIGHTBAR_SETUP_CONTROL_ENABLE …
#define DS_OUTPUT_VALID_FLAG2_COMPATIBLE_VIBRATION2 …
#define DS_OUTPUT_POWER_SAVE_CONTROL_MIC_MUTE …
#define DS_OUTPUT_LIGHTBAR_SETUP_LIGHT_OUT …
#define DS_ACC_RES_PER_G …
#define DS_ACC_RANGE …
#define DS_GYRO_RES_PER_DEG_S …
#define DS_GYRO_RANGE …
#define DS_TOUCHPAD_WIDTH …
#define DS_TOUCHPAD_HEIGHT …
struct dualsense { … };
struct dualsense_touch_point { … } __packed;
static_assert(…);
struct dualsense_input_report { … } __packed;
static_assert(…);
struct dualsense_output_report_common { … } __packed;
static_assert(…);
struct dualsense_output_report_bt { … } __packed;
static_assert(…);
struct dualsense_output_report_usb { … } __packed;
static_assert(…);
struct dualsense_output_report { … };
#define DS4_INPUT_REPORT_USB …
#define DS4_INPUT_REPORT_USB_SIZE …
#define DS4_INPUT_REPORT_BT_MINIMAL …
#define DS4_INPUT_REPORT_BT_MINIMAL_SIZE …
#define DS4_INPUT_REPORT_BT …
#define DS4_INPUT_REPORT_BT_SIZE …
#define DS4_OUTPUT_REPORT_USB …
#define DS4_OUTPUT_REPORT_USB_SIZE …
#define DS4_OUTPUT_REPORT_BT …
#define DS4_OUTPUT_REPORT_BT_SIZE …
#define DS4_FEATURE_REPORT_CALIBRATION …
#define DS4_FEATURE_REPORT_CALIBRATION_SIZE …
#define DS4_FEATURE_REPORT_CALIBRATION_BT …
#define DS4_FEATURE_REPORT_CALIBRATION_BT_SIZE …
#define DS4_FEATURE_REPORT_FIRMWARE_INFO …
#define DS4_FEATURE_REPORT_FIRMWARE_INFO_SIZE …
#define DS4_FEATURE_REPORT_PAIRING_INFO …
#define DS4_FEATURE_REPORT_PAIRING_INFO_SIZE …
#define DS4_TOUCH_POINT_INACTIVE …
#define DS4_STATUS0_BATTERY_CAPACITY …
#define DS4_STATUS0_CABLE_STATE …
#define DS4_BATTERY_STATUS_FULL …
#define DS4_STATUS1_DONGLE_STATE …
#define DS4_OUTPUT_HWCTL_BT_POLL_MASK …
#define DS4_BT_DEFAULT_POLL_INTERVAL_MS …
#define DS4_OUTPUT_HWCTL_CRC32 …
#define DS4_OUTPUT_HWCTL_HID …
#define DS4_OUTPUT_VALID_FLAG0_MOTOR …
#define DS4_OUTPUT_VALID_FLAG0_LED …
#define DS4_OUTPUT_VALID_FLAG0_LED_BLINK …
#define DS4_ACC_RES_PER_G …
#define DS4_ACC_RANGE …
#define DS4_GYRO_RES_PER_DEG_S …
#define DS4_GYRO_RANGE …
#define DS4_LIGHTBAR_MAX_BLINK …
#define DS4_TOUCHPAD_WIDTH …
#define DS4_TOUCHPAD_HEIGHT …
enum dualshock4_dongle_state { … };
struct dualshock4 { … };
struct dualshock4_touch_point { … } __packed;
static_assert(…);
struct dualshock4_touch_report { … } __packed;
static_assert(…);
struct dualshock4_input_report_common { … } __packed;
static_assert(…);
struct dualshock4_input_report_usb { … } __packed;
static_assert(…);
struct dualshock4_input_report_bt { … } __packed;
static_assert(…);
struct dualshock4_output_report_common { … } __packed;
struct dualshock4_output_report_usb { … } __packed;
static_assert(…);
struct dualshock4_output_report_bt { … } __packed;
static_assert(…);
struct dualshock4_output_report { … };
static const int ps_gamepad_buttons[] = …;
static const struct { … } ps_gamepad_hat_mapping[] = …;
static int dualshock4_get_calibration_data(struct dualshock4 *ds4);
static inline void dualsense_schedule_work(struct dualsense *ds);
static inline void dualshock4_schedule_work(struct dualshock4 *ds4);
static void dualsense_set_lightbar(struct dualsense *ds, uint8_t red, uint8_t green, uint8_t blue);
static void dualshock4_set_default_lightbar_colors(struct dualshock4 *ds4);
static int ps_devices_list_add(struct ps_device *dev)
{ … }
static int ps_devices_list_remove(struct ps_device *dev)
{ … }
static int ps_device_set_player_id(struct ps_device *dev)
{ … }
static void ps_device_release_player_id(struct ps_device *dev)
{ … }
static struct input_dev *ps_allocate_input_dev(struct hid_device *hdev, const char *name_suffix)
{ … }
static enum power_supply_property ps_power_supply_props[] = …;
static int ps_battery_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{ … }
static int ps_device_register_battery(struct ps_device *dev)
{ … }
static bool ps_check_crc32(uint8_t seed, uint8_t *data, size_t len, uint32_t report_crc)
{ … }
static struct input_dev *ps_gamepad_create(struct hid_device *hdev,
int (*play_effect)(struct input_dev *, void *, struct ff_effect *))
{ … }
static int ps_get_report(struct hid_device *hdev, uint8_t report_id, uint8_t *buf, size_t size,
bool check_crc)
{ … }
static int ps_led_register(struct ps_device *ps_dev, struct led_classdev *led,
const struct ps_led_info *led_info)
{ … }
static int ps_lightbar_register(struct ps_device *ps_dev, struct led_classdev_mc *lightbar_mc_dev,
int (*brightness_set)(struct led_classdev *, enum led_brightness))
{ … }
static struct input_dev *ps_sensors_create(struct hid_device *hdev, int accel_range, int accel_res,
int gyro_range, int gyro_res)
{ … }
static struct input_dev *ps_touchpad_create(struct hid_device *hdev, int width, int height,
unsigned int num_contacts)
{ … }
static ssize_t firmware_version_show(struct device *dev,
struct device_attribute
*attr, char *buf)
{ … }
static DEVICE_ATTR_RO(firmware_version);
static ssize_t hardware_version_show(struct device *dev,
struct device_attribute
*attr, char *buf)
{ … }
static DEVICE_ATTR_RO(hardware_version);
static struct attribute *ps_device_attrs[] = …;
ATTRIBUTE_GROUPS(…);
static int dualsense_get_calibration_data(struct dualsense *ds)
{ … }
static int dualsense_get_firmware_info(struct dualsense *ds)
{ … }
static int dualsense_get_mac_address(struct dualsense *ds)
{ … }
static int dualsense_lightbar_set_brightness(struct led_classdev *cdev,
enum led_brightness brightness)
{ … }
static enum led_brightness dualsense_player_led_get_brightness(struct led_classdev *led)
{ … }
static int dualsense_player_led_set_brightness(struct led_classdev *led, enum led_brightness value)
{ … }
static void dualsense_init_output_report(struct dualsense *ds, struct dualsense_output_report *rp,
void *buf)
{ … }
static inline void dualsense_schedule_work(struct dualsense *ds)
{ … }
static void dualsense_send_output_report(struct dualsense *ds,
struct dualsense_output_report *report)
{ … }
static void dualsense_output_worker(struct work_struct *work)
{ … }
static int dualsense_parse_report(struct ps_device *ps_dev, struct hid_report *report,
u8 *data, int size)
{ … }
static int dualsense_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
{ … }
static void dualsense_remove(struct ps_device *ps_dev)
{ … }
static int dualsense_reset_leds(struct dualsense *ds)
{ … }
static void dualsense_set_lightbar(struct dualsense *ds, uint8_t red, uint8_t green, uint8_t blue)
{ … }
static void dualsense_set_player_leds(struct dualsense *ds)
{ … }
static struct ps_device *dualsense_create(struct hid_device *hdev)
{ … }
static void dualshock4_dongle_calibration_work(struct work_struct *work)
{ … }
static int dualshock4_get_calibration_data(struct dualshock4 *ds4)
{ … }
static int dualshock4_get_firmware_info(struct dualshock4 *ds4)
{ … }
static int dualshock4_get_mac_address(struct dualshock4 *ds4)
{ … }
static enum led_brightness dualshock4_led_get_brightness(struct led_classdev *led)
{ … }
static int dualshock4_led_set_blink(struct led_classdev *led, unsigned long *delay_on,
unsigned long *delay_off)
{ … }
static int dualshock4_led_set_brightness(struct led_classdev *led, enum led_brightness value)
{ … }
static void dualshock4_init_output_report(struct dualshock4 *ds4,
struct dualshock4_output_report *rp, void *buf)
{ … }
static void dualshock4_output_worker(struct work_struct *work)
{ … }
static int dualshock4_parse_report(struct ps_device *ps_dev, struct hid_report *report,
u8 *data, int size)
{ … }
static int dualshock4_dongle_parse_report(struct ps_device *ps_dev, struct hid_report *report,
u8 *data, int size)
{ … }
static int dualshock4_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
{ … }
static void dualshock4_remove(struct ps_device *ps_dev)
{ … }
static inline void dualshock4_schedule_work(struct dualshock4 *ds4)
{ … }
static void dualshock4_set_bt_poll_interval(struct dualshock4 *ds4, uint8_t interval)
{ … }
static void dualshock4_set_default_lightbar_colors(struct dualshock4 *ds4)
{ … }
static struct ps_device *dualshock4_create(struct hid_device *hdev)
{ … }
static int ps_raw_event(struct hid_device *hdev, struct hid_report *report,
u8 *data, int size)
{ … }
static int ps_probe(struct hid_device *hdev, const struct hid_device_id *id)
{ … }
static void ps_remove(struct hid_device *hdev)
{ … }
static const struct hid_device_id ps_devices[] = …;
MODULE_DEVICE_TABLE(hid, ps_devices);
static struct hid_driver ps_driver = …;
static int __init ps_init(void)
{ … }
static void __exit ps_exit(void)
{ … }
module_init(…) …;
module_exit(ps_exit);
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;