drivers/input/keyboard/charlieplex_keypad.c
Source file repositories/reference/linux-study-clean/drivers/input/keyboard/charlieplex_keypad.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/input/keyboard/charlieplex_keypad.c- Extension
.c- Size
- 6350 bytes
- Lines
- 233
- Domain
- Driver Families
- Bucket
- drivers/input
- 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/bitops.hlinux/delay.hlinux/dev_printk.hlinux/device/devres.hlinux/err.hlinux/gpio/consumer.hlinux/input.hlinux/input/matrix_keypad.hlinux/math.hlinux/module.hlinux/mod_devicetable.hlinux/platform_device.hlinux/property.hlinux/string_helpers.hlinux/types.h
Detected Declarations
struct charlieplex_keypadfunction charlieplex_keypad_report_keyfunction charlieplex_keypad_check_switch_changefunction charlieplex_keypad_scan_linefunction charlieplex_keypad_pollfunction charlieplex_keypad_init_gpiofunction charlieplex_keypad_probe
Annotated Snippet
struct charlieplex_keypad {
struct input_dev *input_dev;
struct gpio_descs *line_gpios;
unsigned int nlines;
unsigned int settling_time_us;
unsigned int debounce_threshold;
unsigned int debounce_count;
int debounce_code;
int current_code;
};
static void charlieplex_keypad_report_key(struct input_dev *input)
{
struct charlieplex_keypad *keypad = input_get_drvdata(input);
const unsigned short *keycodes = input->keycode;
if (keypad->current_code > 0) {
input_event(input, EV_MSC, MSC_SCAN, keypad->current_code);
input_report_key(input, keycodes[keypad->current_code], 0);
input_sync(input);
}
if (keypad->debounce_code) {
input_event(input, EV_MSC, MSC_SCAN, keypad->debounce_code);
input_report_key(input, keycodes[keypad->debounce_code], 1);
input_sync(input);
}
keypad->current_code = keypad->debounce_code;
}
static void charlieplex_keypad_check_switch_change(struct input_dev *input,
unsigned int code)
{
struct charlieplex_keypad *keypad = input_get_drvdata(input);
if (code != keypad->debounce_code) {
keypad->debounce_count = 0;
keypad->debounce_code = code;
}
if (keypad->debounce_code != keypad->current_code) {
if (keypad->debounce_count++ >= keypad->debounce_threshold)
charlieplex_keypad_report_key(input);
}
}
static int charlieplex_keypad_scan_line(struct charlieplex_keypad *keypad,
unsigned int oline)
{
struct gpio_descs *line_gpios = keypad->line_gpios;
DECLARE_BITMAP(values, MATRIX_MAX_ROWS);
int err;
/* Activate only one line as output at a time. */
gpiod_direction_output(line_gpios->desc[oline], 1);
if (keypad->settling_time_us)
fsleep(keypad->settling_time_us);
/* Read input on all other lines. */
err = gpiod_get_array_value_cansleep(line_gpios->ndescs, line_gpios->desc,
line_gpios->info, values);
gpiod_direction_input(line_gpios->desc[oline]);
if (err)
return err;
for (unsigned int iline = 0; iline < keypad->nlines; iline++) {
if (iline == oline)
continue; /* Do not read active output line. */
/* Check if GPIO is asserted. */
if (test_bit(iline, values))
return MATRIX_SCAN_CODE(oline, iline,
get_count_order(keypad->nlines));
}
return 0;
}
static void charlieplex_keypad_poll(struct input_dev *input)
{
struct charlieplex_keypad *keypad = input_get_drvdata(input);
int code = 0;
for (unsigned int oline = 0; oline < keypad->nlines; oline++) {
code = charlieplex_keypad_scan_line(keypad, oline);
if (code != 0)
Annotation
- Immediate include surface: `linux/bitops.h`, `linux/delay.h`, `linux/dev_printk.h`, `linux/device/devres.h`, `linux/err.h`, `linux/gpio/consumer.h`, `linux/input.h`, `linux/input/matrix_keypad.h`.
- Detected declarations: `struct charlieplex_keypad`, `function charlieplex_keypad_report_key`, `function charlieplex_keypad_check_switch_change`, `function charlieplex_keypad_scan_line`, `function charlieplex_keypad_poll`, `function charlieplex_keypad_init_gpio`, `function charlieplex_keypad_probe`.
- Atlas domain: Driver Families / drivers/input.
- 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.