drivers/hid/surface-hid/surface_kbd.c
Source file repositories/reference/linux-study-clean/drivers/hid/surface-hid/surface_kbd.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/hid/surface-hid/surface_kbd.c- Extension
.c- Size
- 7914 bytes
- Lines
- 300
- Domain
- Driver Families
- Bucket
- drivers/hid
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/unaligned.hlinux/hid.hlinux/kernel.hlinux/module.hlinux/platform_device.hlinux/types.hlinux/surface_aggregator/controller.hsurface_hid_core.h
Detected Declarations
enum surface_kbd_cidfunction ssam_kbd_get_descriptorfunction ssam_kbd_set_caps_ledfunction ssam_kbd_get_feature_reportfunction ssam_kbd_is_input_eventfunction ssam_kbd_event_fnfunction skbd_get_caps_led_valuefunction skbd_output_reportfunction skbd_get_feature_reportfunction skbd_set_feature_reportfunction surface_kbd_probefunction surface_kbd_remove
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0+
/*
* Surface System Aggregator Module (SSAM) HID transport driver for the legacy
* keyboard interface (KBD/TC=0x08 subsystem). Provides support for the
* integrated HID keyboard on Surface Laptops 1 and 2.
*
* Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
*/
#include <linux/unaligned.h>
#include <linux/hid.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/surface_aggregator/controller.h>
#include "surface_hid_core.h"
/* -- SAM interface (KBD). -------------------------------------------------- */
#define KBD_FEATURE_REPORT_SIZE 7 /* 6 + report ID */
enum surface_kbd_cid {
SURFACE_KBD_CID_GET_DESCRIPTOR = 0x00,
SURFACE_KBD_CID_SET_CAPSLOCK_LED = 0x01,
SURFACE_KBD_CID_EVT_INPUT_GENERIC = 0x03,
SURFACE_KBD_CID_EVT_INPUT_HOTKEYS = 0x04,
SURFACE_KBD_CID_GET_FEATURE_REPORT = 0x0b,
};
static int ssam_kbd_get_descriptor(struct surface_hid_device *shid, u8 entry, u8 *buf, size_t len)
{
struct ssam_request rqst;
struct ssam_response rsp;
int status;
rqst.target_category = shid->uid.category;
rqst.target_id = shid->uid.target;
rqst.command_id = SURFACE_KBD_CID_GET_DESCRIPTOR;
rqst.instance_id = shid->uid.instance;
rqst.flags = SSAM_REQUEST_HAS_RESPONSE;
rqst.length = sizeof(entry);
rqst.payload = &entry;
rsp.capacity = len;
rsp.length = 0;
rsp.pointer = buf;
status = ssam_retry(ssam_request_do_sync_onstack, shid->ctrl, &rqst, &rsp, sizeof(entry));
if (status)
return status;
if (rsp.length != len) {
dev_err(shid->dev, "invalid descriptor length: got %zu, expected, %zu\n",
rsp.length, len);
return -EPROTO;
}
return 0;
}
static int ssam_kbd_set_caps_led(struct surface_hid_device *shid, bool value)
{
struct ssam_request rqst;
u8 value_u8 = value;
rqst.target_category = shid->uid.category;
rqst.target_id = shid->uid.target;
rqst.command_id = SURFACE_KBD_CID_SET_CAPSLOCK_LED;
rqst.instance_id = shid->uid.instance;
rqst.flags = 0;
rqst.length = sizeof(value_u8);
rqst.payload = &value_u8;
return ssam_retry(ssam_request_do_sync_onstack, shid->ctrl, &rqst, NULL, sizeof(value_u8));
}
static int ssam_kbd_get_feature_report(struct surface_hid_device *shid, u8 *buf, size_t len)
{
struct ssam_request rqst;
struct ssam_response rsp;
u8 payload = 0;
int status;
rqst.target_category = shid->uid.category;
rqst.target_id = shid->uid.target;
rqst.command_id = SURFACE_KBD_CID_GET_FEATURE_REPORT;
Annotation
- Immediate include surface: `linux/unaligned.h`, `linux/hid.h`, `linux/kernel.h`, `linux/module.h`, `linux/platform_device.h`, `linux/types.h`, `linux/surface_aggregator/controller.h`, `surface_hid_core.h`.
- Detected declarations: `enum surface_kbd_cid`, `function ssam_kbd_get_descriptor`, `function ssam_kbd_set_caps_led`, `function ssam_kbd_get_feature_report`, `function ssam_kbd_is_input_event`, `function ssam_kbd_event_fn`, `function skbd_get_caps_led_value`, `function skbd_output_report`, `function skbd_get_feature_report`, `function skbd_set_feature_report`.
- Atlas domain: Driver Families / drivers/hid.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.