drivers/hid/hid-lenovo.c
Source file repositories/reference/linux-study-clean/drivers/hid/hid-lenovo.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/hid/hid-lenovo.c- Extension
.c- Size
- 45556 bytes
- Lines
- 1592
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/module.hlinux/sysfs.hlinux/device.hlinux/hid.hlinux/input.hlinux/leds.hlinux/unaligned.hlinux/workqueue.hhid-ids.h
Detected Declarations
struct lenovo_drvdatafunction report_key_eventfunction lenovo_led_set_tp10ubkbdfunction lenovo_tp10ubkbd_sync_fn_lockfunction lenovo_input_mapping_tpkbdfunction lenovo_input_mapping_cptkbdfunction lenovo_input_mapping_tpIIkbdfunction lenovo_input_mapping_scrollpointfunction lenovo_input_mapping_tp10_ultrabook_kbdfunction lenovo_input_mapping_x1_tab_kbdfunction lenovo_input_mappingfunction lenovo_send_cmd_cptkbdfunction lenovo_features_set_cptkbdfunction keysfunction attr_fn_lock_showfunction attr_fn_lock_storefunction attr_sensitivity_show_cptkbdfunction attr_sensitivity_store_cptkbdfunction attr_middleclick_workaround_show_cptkbdfunction attr_middleclick_workaround_store_cptkbdfunction lenovo_raw_event_TP_X12_tabfunction lenovo_raw_eventfunction lenovo_event_tp10ubkbdfunction lenovo_event_cptkbdfunction lenovo_eventfunction lenovo_features_set_tpkbdfunction attr_press_to_select_show_tpkbdfunction attr_press_to_select_store_tpkbdfunction attr_dragging_show_tpkbdfunction attr_dragging_store_tpkbdfunction attr_release_to_select_show_tpkbdfunction attr_release_to_select_store_tpkbdfunction attr_select_right_show_tpkbdfunction attr_select_right_store_tpkbdfunction attr_sensitivity_show_tpkbdfunction attr_sensitivity_store_tpkbdfunction attr_press_speed_show_tpkbdfunction attr_press_speed_store_tpkbdfunction lenovo_led_set_tpkbdfunction lenovo_led_brightness_setfunction lenovo_register_ledsfunction lenovo_probe_tpkbdfunction lenovo_probe_cptkbdfunction lenovo_probe_tp10ubkbdfunction lenovo_probefunction lenovo_reset_resumefunction lenovo_remove_tpkbdfunction lenovo_remove_cptkbd
Annotated Snippet
struct lenovo_drvdata {
u8 led_report[3]; /* Must be first for proper alignment */
int led_state;
struct mutex led_report_mutex;
struct led_classdev led_mute;
struct led_classdev led_micmute;
struct work_struct fn_lock_sync_work;
struct hid_device *hdev;
int press_to_select;
int dragging;
int release_to_select;
int select_right;
int sensitivity;
int press_speed;
/* 0: Up
* 1: Down (undecided)
* 2: Scrolling
*/
u8 middlebutton_state;
bool fn_lock;
bool middleclick_workaround_cptkbd;
};
#define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
#define TP10UBKBD_LED_OUTPUT_REPORT 9
#define TP10UBKBD_FN_LOCK_LED 0x54
#define TP10UBKBD_MUTE_LED 0x64
#define TP10UBKBD_MICMUTE_LED 0x74
#define TP10UBKBD_LED_OFF 1
#define TP10UBKBD_LED_ON 2
/* Function to report raw_events as key events*/
static inline void report_key_event(struct input_dev *input, int keycode)
{
input_report_key(input, keycode, 1);
input_report_key(input, keycode, 0);
input_sync(input);
}
static int lenovo_led_set_tp10ubkbd(struct hid_device *hdev, u8 led_code,
enum led_brightness value)
{
struct lenovo_drvdata *data = hid_get_drvdata(hdev);
int ret;
mutex_lock(&data->led_report_mutex);
data->led_report[0] = TP10UBKBD_LED_OUTPUT_REPORT;
data->led_report[1] = led_code;
data->led_report[2] = value ? TP10UBKBD_LED_ON : TP10UBKBD_LED_OFF;
ret = hid_hw_raw_request(hdev, data->led_report[0], data->led_report, 3,
HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
if (ret != 3) {
if (ret != -ENODEV)
hid_err(hdev, "Set LED output report error: %d\n", ret);
ret = ret < 0 ? ret : -EIO;
} else {
ret = 0;
}
mutex_unlock(&data->led_report_mutex);
return ret;
}
static void lenovo_tp10ubkbd_sync_fn_lock(struct work_struct *work)
{
struct lenovo_drvdata *data =
container_of(work, struct lenovo_drvdata, fn_lock_sync_work);
lenovo_led_set_tp10ubkbd(data->hdev, TP10UBKBD_FN_LOCK_LED,
data->fn_lock);
}
static const __u8 lenovo_pro_dock_need_fixup_collection[] = {
0x05, 0x88, /* Usage Page (Vendor Usage Page 0x88) */
0x09, 0x01, /* Usage (Vendor Usage 0x01) */
0xa1, 0x01, /* Collection (Application) */
0x85, 0x04, /* Report ID (4) */
0x19, 0x00, /* Usage Minimum (0) */
0x2a, 0xff, 0xff, /* Usage Maximum (65535) */
};
/* Broken ThinkPad TrackPoint II collection (Bluetooth mode) */
static const __u8 lenovo_tpIIbtkbd_need_fixup_collection[] = {
0x06, 0x00, 0xFF, /* Usage Page (Vendor Defined 0xFF00) */
Annotation
- Immediate include surface: `linux/module.h`, `linux/sysfs.h`, `linux/device.h`, `linux/hid.h`, `linux/input.h`, `linux/leds.h`, `linux/unaligned.h`, `linux/workqueue.h`.
- Detected declarations: `struct lenovo_drvdata`, `function report_key_event`, `function lenovo_led_set_tp10ubkbd`, `function lenovo_tp10ubkbd_sync_fn_lock`, `function lenovo_input_mapping_tpkbd`, `function lenovo_input_mapping_cptkbd`, `function lenovo_input_mapping_tpIIkbd`, `function lenovo_input_mapping_scrollpoint`, `function lenovo_input_mapping_tp10_ultrabook_kbd`, `function lenovo_input_mapping_x1_tab_kbd`.
- Atlas domain: Driver Families / drivers/hid.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.