drivers/hid/hid-lg-g15.c
Source file repositories/reference/linux-study-clean/drivers/hid/hid-lg-g15.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/hid/hid-lg-g15.c- Extension
.c- Size
- 37812 bytes
- Lines
- 1388
- 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/device.hlinux/hid.hlinux/leds.hlinux/led-class-multicolor.hlinux/module.hlinux/random.hlinux/sched.hlinux/usb.hlinux/wait.hdt-bindings/leds/common.hhid-ids.h
Detected Declarations
struct g13_input_reportstruct lg_g15_ledstruct lg_g15_dataenum lg_g15_modelenum lg_g15_led_typefunction lg_g13_get_leds_statefunction lg_g13_kbd_led_writefunction lg_g13_kbd_led_setfunction lg_g13_kbd_led_getfunction lg_g13_mkey_led_setfunction lg_g13_mkey_led_getfunction lg_g15_update_led_brightnessfunction lg_g15_led_getfunction lg_g15_led_setfunction lg_g15_leds_changed_workfunction lg_g510_get_initial_led_brightnessfunction lg_g510_kbd_led_writefunction lg_g510_kbd_led_setfunction lg_g510_kbd_led_getfunction lg_g510_leds_sync_workfunction lg_g510_update_mkey_led_brightnessfunction lg_g510_mkey_led_getfunction lg_g510_mkey_led_setfunction lg_g15_get_initial_led_brightnessfunction lg_g13_eventfunction lg_g15_handle_lcd_menu_keysfunction lg_g15_eventfunction lg_g15_v2_eventfunction lg_g510_eventfunction lg_g510_leds_eventfunction lg_g15_raw_eventfunction lg_g15_input_openfunction lg_g15_input_closefunction lg_g15_setup_led_rgbfunction lg_g15_register_ledfunction lg_g15_init_input_dev_corefunction lg_g15_init_input_devfunction lg_g13_init_input_devfunction lg_g15_probefunction mute
Annotated Snippet
struct g13_input_report {
u8 report_id; /* Report ID is always set to 1. */
u8 joy_x, joy_y;
u8 keybits[5];
};
struct lg_g15_led {
union {
struct led_classdev cdev;
struct led_classdev_mc mcdev;
};
enum led_brightness brightness;
enum lg_g15_led_type led;
/* Used to store initial color intensities before subled_info is allocated */
u8 red, green, blue;
};
struct lg_g15_data {
/* Must be first for proper dma alignment */
u8 transfer_buf[LG_G15_TRANSFER_BUF_SIZE];
/* Protects the transfer_buf and led brightness */
struct mutex mutex;
struct work_struct work;
struct input_dev *input;
struct input_dev *input_js; /* Separate joystick device for G13. */
struct hid_device *hdev;
enum lg_g15_model model;
struct lg_g15_led leds[LG_G15_LED_MAX];
bool game_mode_enabled;
bool backlight_disabled; /* true == HW backlight toggled *OFF* */
};
/********* G13 LED functions ***********/
/*
* G13 retains no state across power cycles, and always powers up with the backlight on,
* color #5AFF6E, all macro key LEDs off.
*/
static int lg_g13_get_leds_state(struct lg_g15_data *g15)
{
u8 * const tbuf = g15->transfer_buf;
int ret, high;
/* RGB backlight. */
ret = hid_hw_raw_request(g15->hdev, LG_G13_FEATURE_BACKLIGHT_RGB,
tbuf, 5,
HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
if (ret != 5) {
hid_err(g15->hdev, "Error getting backlight brightness: %d\n", ret);
return (ret < 0) ? ret : -EIO;
}
/* Normalize RGB intensities against the highest component. */
high = max3(tbuf[1], tbuf[2], tbuf[3]);
if (high) {
g15->leds[LG_G15_KBD_BRIGHTNESS].red =
DIV_ROUND_CLOSEST(tbuf[1] * 255, high);
g15->leds[LG_G15_KBD_BRIGHTNESS].green =
DIV_ROUND_CLOSEST(tbuf[2] * 255, high);
g15->leds[LG_G15_KBD_BRIGHTNESS].blue =
DIV_ROUND_CLOSEST(tbuf[3] * 255, high);
g15->leds[LG_G15_KBD_BRIGHTNESS].brightness = high;
} else {
g15->leds[LG_G15_KBD_BRIGHTNESS].red = 255;
g15->leds[LG_G15_KBD_BRIGHTNESS].green = 255;
g15->leds[LG_G15_KBD_BRIGHTNESS].blue = 255;
g15->leds[LG_G15_KBD_BRIGHTNESS].brightness = 0;
}
/* Macro LEDs. */
ret = hid_hw_raw_request(g15->hdev, LG_G13_FEATURE_M_KEYS_LEDS,
tbuf, 5,
HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
if (ret != 5) {
hid_err(g15->hdev, "Error getting macro LED brightness: %d\n", ret);
return (ret < 0) ? ret : -EIO;
}
for (int i = LG_G15_MACRO_PRESET1; i < LG_G15_LED_MAX; ++i)
g15->leds[i].brightness = !!(tbuf[1] & (1 << (i - LG_G15_MACRO_PRESET1)));
/*
* Bit 23 of g13_input_report.keybits[] contains the backlight's
* current HW toggle state. Retrieve it from the device.
*/
ret = hid_hw_raw_request(g15->hdev, LG_G13_INPUT_REPORT,
tbuf, sizeof(struct g13_input_report),
HID_INPUT_REPORT, HID_REQ_GET_REPORT);
if (ret != sizeof(struct g13_input_report)) {
hid_err(g15->hdev, "Error getting backlight on/off state: %d\n", ret);
return (ret < 0) ? ret : -EIO;
Annotation
- Immediate include surface: `linux/device.h`, `linux/hid.h`, `linux/leds.h`, `linux/led-class-multicolor.h`, `linux/module.h`, `linux/random.h`, `linux/sched.h`, `linux/usb.h`.
- Detected declarations: `struct g13_input_report`, `struct lg_g15_led`, `struct lg_g15_data`, `enum lg_g15_model`, `enum lg_g15_led_type`, `function lg_g13_get_leds_state`, `function lg_g13_kbd_led_write`, `function lg_g13_kbd_led_set`, `function lg_g13_kbd_led_get`, `function lg_g13_mkey_led_set`.
- 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.