1 /* SPDX-License-Identifier: GPL-2.0+ */ 2 /* 3 * Common/core components for the Surface System Aggregator Module (SSAM) HID 4 * transport driver. Provides support for integrated HID devices on Microsoft 5 * Surface models. 6 * 7 * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> 8 */ 9 10 #ifndef SURFACE_HID_CORE_H 11 #define SURFACE_HID_CORE_H 12 13 #include <linux/hid.h> 14 #include <linux/pm.h> 15 #include <linux/types.h> 16 17 #include <linux/surface_aggregator/controller.h> 18 #include <linux/surface_aggregator/device.h> 19 20 enum surface_hid_descriptor_entry { 21 SURFACE_HID_DESC_HID = 0, 22 SURFACE_HID_DESC_REPORT = 1, 23 SURFACE_HID_DESC_ATTRS = 2, 24 }; 25 26 struct surface_hid_descriptor { 27 __u8 desc_len; /* = 9 */ 28 __u8 desc_type; /* = HID_DT_HID */ 29 __le16 hid_version; 30 __u8 country_code; 31 __u8 num_descriptors; /* = 1 */ 32 33 __u8 report_desc_type; /* = HID_DT_REPORT */ 34 __le16 report_desc_len; 35 } __packed; 36 37 static_assert(sizeof(struct surface_hid_descriptor) == 9); 38 39 struct surface_hid_attributes { 40 __le32 length; 41 __le16 vendor; 42 __le16 product; 43 __le16 version; 44 __u8 _unknown[22]; 45 } __packed; 46 47 static_assert(sizeof(struct surface_hid_attributes) == 32); 48 49 struct surface_hid_device; 50 51 struct surface_hid_device_ops { 52 int (*get_descriptor)(struct surface_hid_device *shid, u8 entry, u8 *buf, size_t len); 53 int (*output_report)(struct surface_hid_device *shid, u8 rprt_id, u8 *buf, size_t len); 54 int (*get_feature_report)(struct surface_hid_device *shid, u8 rprt_id, u8 *buf, size_t len); 55 int (*set_feature_report)(struct surface_hid_device *shid, u8 rprt_id, u8 *buf, size_t len); 56 }; 57 58 struct surface_hid_device { 59 struct device *dev; 60 struct ssam_controller *ctrl; 61 struct ssam_device_uid uid; 62 63 struct surface_hid_descriptor hid_desc; 64 struct surface_hid_attributes attrs; 65 66 struct ssam_event_notifier notif; 67 struct hid_device *hid; 68 69 struct surface_hid_device_ops ops; 70 }; 71 72 int surface_hid_device_add(struct surface_hid_device *shid); 73 void surface_hid_device_destroy(struct surface_hid_device *shid); 74 75 extern const struct dev_pm_ops surface_hid_pm_ops; 76 77 #endif /* SURFACE_HID_CORE_H */ 78