Lines Matching +full:surface +full:- +full:sam
1 // SPDX-License-Identifier: GPL-2.0+
3 * Surface System Aggregator Module (SSAM) HID transport driver for the
5 * integrated HID devices on Surface Laptop 3, Book 3, and later.
7 * Copyright (C) 2019-2021 Blaž Hrastnik <[email protected]>,
23 /* -- SAM interface. -------------------------------------------------------- */
57 buffer_len = ARRAY_SIZE(buffer) - sizeof(struct surface_hid_buffer_slice); in ssam_hid_get_descriptor()
59 rqst.target_category = shid->uid.category; in ssam_hid_get_descriptor()
60 rqst.target_id = shid->uid.target; in ssam_hid_get_descriptor()
62 rqst.instance_id = shid->uid.instance; in ssam_hid_get_descriptor()
71 slice->entry = entry; in ssam_hid_get_descriptor()
72 slice->end = 0; in ssam_hid_get_descriptor()
77 while (!slice->end && offset < len) { in ssam_hid_get_descriptor()
78 put_unaligned_le32(offset, &slice->offset); in ssam_hid_get_descriptor()
79 put_unaligned_le32(length, &slice->length); in ssam_hid_get_descriptor()
83 status = ssam_retry(ssam_request_do_sync_onstack, shid->ctrl, &rqst, &rsp, in ssam_hid_get_descriptor()
88 offset = get_unaligned_le32(&slice->offset); in ssam_hid_get_descriptor()
89 length = get_unaligned_le32(&slice->length); in ssam_hid_get_descriptor()
93 return -EPROTO; in ssam_hid_get_descriptor()
96 length = len - offset; in ssam_hid_get_descriptor()
98 memcpy(buf + offset, &slice->data[0], length); in ssam_hid_get_descriptor()
105 dev_err(shid->dev, "unexpected descriptor length: got %u, expected %zu\n", in ssam_hid_get_descriptor()
107 return -EPROTO; in ssam_hid_get_descriptor()
124 rqst.target_category = shid->uid.category; in ssam_hid_set_raw_report()
125 rqst.target_id = shid->uid.target; in ssam_hid_set_raw_report()
126 rqst.instance_id = shid->uid.instance; in ssam_hid_set_raw_report()
134 return ssam_retry(ssam_request_do_sync, shid->ctrl, &rqst, NULL); in ssam_hid_set_raw_report()
142 rqst.target_category = shid->uid.category; in ssam_hid_get_raw_report()
143 rqst.target_id = shid->uid.target; in ssam_hid_get_raw_report()
144 rqst.instance_id = shid->uid.instance; in ssam_hid_get_raw_report()
154 return ssam_retry(ssam_request_do_sync_onstack, shid->ctrl, &rqst, &rsp, sizeof(rprt_id)); in ssam_hid_get_raw_report()
161 if (event->command_id != 0x00) in ssam_hid_event_fn()
164 hid_input_report(shid->hid, HID_INPUT_REPORT, (u8 *)&event->data[0], event->length, 0); in ssam_hid_event_fn()
169 /* -- Transport driver. ----------------------------------------------------- */
196 /* -- Driver setup. --------------------------------------------------------- */
202 shid = devm_kzalloc(&sdev->dev, sizeof(*shid), GFP_KERNEL); in surface_hid_probe()
204 return -ENOMEM; in surface_hid_probe()
206 shid->dev = &sdev->dev; in surface_hid_probe()
207 shid->ctrl = sdev->ctrl; in surface_hid_probe()
208 shid->uid = sdev->uid; in surface_hid_probe()
210 shid->notif.base.priority = 1; in surface_hid_probe()
211 shid->notif.base.fn = ssam_hid_event_fn; in surface_hid_probe()
212 shid->notif.event.reg = SSAM_EVENT_REGISTRY_REG(sdev->uid.target); in surface_hid_probe()
213 shid->notif.event.id.target_category = sdev->uid.category; in surface_hid_probe()
214 shid->notif.event.id.instance = sdev->uid.instance; in surface_hid_probe()
215 shid->notif.event.mask = SSAM_EVENT_MASK_STRICT; in surface_hid_probe()
216 shid->notif.event.flags = 0; in surface_hid_probe()
218 shid->ops.get_descriptor = ssam_hid_get_descriptor; in surface_hid_probe()
219 shid->ops.output_report = shid_output_report; in surface_hid_probe()
220 shid->ops.get_feature_report = shid_get_feature_report; in surface_hid_probe()
221 shid->ops.set_feature_report = shid_set_feature_report; in surface_hid_probe()
252 MODULE_DESCRIPTION("HID transport driver for Surface System Aggregator Module");