Lines Matching +full:ctrl +full:- +full:len

1 // SPDX-License-Identifier: GPL-2.0+
7 * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
22 /* -- SAM interface (KBD). -------------------------------------------------- */
34 static int ssam_kbd_get_descriptor(struct surface_hid_device *shid, u8 entry, u8 *buf, size_t len) in ssam_kbd_get_descriptor() argument
40 rqst.target_category = shid->uid.category; in ssam_kbd_get_descriptor()
41 rqst.target_id = shid->uid.target; in ssam_kbd_get_descriptor()
43 rqst.instance_id = shid->uid.instance; in ssam_kbd_get_descriptor()
48 rsp.capacity = len; in ssam_kbd_get_descriptor()
52 status = ssam_retry(ssam_request_do_sync_onstack, shid->ctrl, &rqst, &rsp, sizeof(entry)); in ssam_kbd_get_descriptor()
56 if (rsp.length != len) { in ssam_kbd_get_descriptor()
57 dev_err(shid->dev, "invalid descriptor length: got %zu, expected, %zu\n", in ssam_kbd_get_descriptor()
58 rsp.length, len); in ssam_kbd_get_descriptor()
59 return -EPROTO; in ssam_kbd_get_descriptor()
70 rqst.target_category = shid->uid.category; in ssam_kbd_set_caps_led()
71 rqst.target_id = shid->uid.target; in ssam_kbd_set_caps_led()
73 rqst.instance_id = shid->uid.instance; in ssam_kbd_set_caps_led()
78 return ssam_retry(ssam_request_do_sync_onstack, shid->ctrl, &rqst, NULL, sizeof(value_u8)); in ssam_kbd_set_caps_led()
81 static int ssam_kbd_get_feature_report(struct surface_hid_device *shid, u8 *buf, size_t len) in ssam_kbd_get_feature_report() argument
88 rqst.target_category = shid->uid.category; in ssam_kbd_get_feature_report()
89 rqst.target_id = shid->uid.target; in ssam_kbd_get_feature_report()
91 rqst.instance_id = shid->uid.instance; in ssam_kbd_get_feature_report()
96 rsp.capacity = len; in ssam_kbd_get_feature_report()
100 status = ssam_retry(ssam_request_do_sync_onstack, shid->ctrl, &rqst, &rsp, sizeof(payload)); in ssam_kbd_get_feature_report()
104 if (rsp.length != len) { in ssam_kbd_get_feature_report()
105 dev_err(shid->dev, "invalid feature report length: got %zu, expected, %zu\n", in ssam_kbd_get_feature_report()
106 rsp.length, len); in ssam_kbd_get_feature_report()
107 return -EPROTO; in ssam_kbd_get_feature_report()
115 if (event->command_id == SURFACE_KBD_CID_EVT_INPUT_GENERIC) in ssam_kbd_is_input_event()
118 if (event->command_id == SURFACE_KBD_CID_EVT_INPUT_HOTKEYS) in ssam_kbd_is_input_event()
133 if (shid->uid.category != event->target_category) in ssam_kbd_event_fn()
136 if (shid->uid.target != event->target_id) in ssam_kbd_event_fn()
139 if (shid->uid.instance != event->instance_id) in ssam_kbd_event_fn()
145 hid_input_report(shid->hid, HID_INPUT_REPORT, (u8 *)&event->data[0], event->length, 0); in ssam_kbd_event_fn()
150 /* -- Transport driver (KBD). ----------------------------------------------- */
152 static int skbd_get_caps_led_value(struct hid_device *hid, u8 rprt_id, u8 *buf, size_t len) in skbd_get_caps_led_value() argument
161 return -ENOENT; in skbd_get_caps_led_value()
164 if (len != hid_report_len(field->report)) in skbd_get_caps_led_value()
165 return -ENOENT; in skbd_get_caps_led_value()
167 if (rprt_id != field->report->id) in skbd_get_caps_led_value()
168 return -ENOENT; in skbd_get_caps_led_value()
171 for (i = 0; i < field->report_count; i++) in skbd_get_caps_led_value()
172 if ((field->usage[i].hid & 0xffff) == 0x02) in skbd_get_caps_led_value()
175 if (i == field->report_count) in skbd_get_caps_led_value()
176 return -ENOENT; in skbd_get_caps_led_value()
179 size = field->report_size; in skbd_get_caps_led_value()
180 offset = field->report_offset + i * size; in skbd_get_caps_led_value()
184 static int skbd_output_report(struct surface_hid_device *shid, u8 rprt_id, u8 *buf, size_t len) in skbd_output_report() argument
189 caps_led = skbd_get_caps_led_value(shid->hid, rprt_id, buf, len); in skbd_output_report()
191 return -EIO; /* Only caps LED output reports are supported. */ in skbd_output_report()
197 return len; in skbd_output_report()
200 static int skbd_get_feature_report(struct surface_hid_device *shid, u8 rprt_id, u8 *buf, size_t len) in skbd_get_feature_report() argument
206 * The keyboard only has a single hard-coded read-only feature report in skbd_get_feature_report()
211 if (len < ARRAY_SIZE(report)) in skbd_get_feature_report()
212 return -ENOSPC; in skbd_get_feature_report()
219 return -ENOENT; in skbd_get_feature_report()
222 return len; in skbd_get_feature_report()
225 static int skbd_set_feature_report(struct surface_hid_device *shid, u8 rprt_id, u8 *buf, size_t len) in skbd_set_feature_report() argument
228 return -EIO; in skbd_set_feature_report()
232 /* -- Driver setup. --------------------------------------------------------- */
236 struct ssam_controller *ctrl; in surface_kbd_probe() local
240 ctrl = ssam_client_bind(&pdev->dev); in surface_kbd_probe()
241 if (IS_ERR(ctrl)) in surface_kbd_probe()
242 return PTR_ERR(ctrl) == -ENODEV ? -EPROBE_DEFER : PTR_ERR(ctrl); in surface_kbd_probe()
244 shid = devm_kzalloc(&pdev->dev, sizeof(*shid), GFP_KERNEL); in surface_kbd_probe()
246 return -ENOMEM; in surface_kbd_probe()
248 shid->dev = &pdev->dev; in surface_kbd_probe()
249 shid->ctrl = ctrl; in surface_kbd_probe()
251 shid->uid.domain = SSAM_DOMAIN_SERIALHUB; in surface_kbd_probe()
252 shid->uid.category = SSAM_SSH_TC_KBD; in surface_kbd_probe()
253 shid->uid.target = SSAM_SSH_TID_KIP; in surface_kbd_probe()
254 shid->uid.instance = 0; in surface_kbd_probe()
255 shid->uid.function = 0; in surface_kbd_probe()
257 shid->notif.base.priority = 1; in surface_kbd_probe()
258 shid->notif.base.fn = ssam_kbd_event_fn; in surface_kbd_probe()
259 shid->notif.event.reg = SSAM_EVENT_REGISTRY_SAM; in surface_kbd_probe()
260 shid->notif.event.id.target_category = shid->uid.category; in surface_kbd_probe()
261 shid->notif.event.id.instance = shid->uid.instance; in surface_kbd_probe()
262 shid->notif.event.mask = SSAM_EVENT_MASK_NONE; in surface_kbd_probe()
263 shid->notif.event.flags = 0; in surface_kbd_probe()
265 shid->ops.get_descriptor = ssam_kbd_get_descriptor; in surface_kbd_probe()
266 shid->ops.output_report = skbd_output_report; in surface_kbd_probe()
267 shid->ops.get_feature_report = skbd_get_feature_report; in surface_kbd_probe()
268 shid->ops.set_feature_report = skbd_set_feature_report; in surface_kbd_probe()