Maximilian Luz | b05ff10 | 2021-03-10 23:53:28 +0100 | [diff] [blame] | 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 */ |