drivers/input/keyboard/max7360-keypad.c
Source file repositories/reference/linux-study-clean/drivers/input/keyboard/max7360-keypad.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/input/keyboard/max7360-keypad.c- Extension
.c- Size
- 8890 bytes
- Lines
- 309
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/bitfield.hlinux/bitops.hlinux/dev_printk.hlinux/device/devres.hlinux/err.hlinux/init.hlinux/input.hlinux/input/matrix_keypad.hlinux/interrupt.hlinux/mfd/max7360.hlinux/mod_devicetable.hlinux/minmax.hlinux/module.hlinux/property.hlinux/platform_device.hlinux/pm_wakeirq.hlinux/regmap.h
Detected Declarations
struct max7360_keypadfunction max7360_keypad_irqfunction max7360_keypad_openfunction max7360_keypad_closefunction max7360_keypad_hw_initfunction max7360_keypad_build_keymapfunction max7360_keypad_parse_fwfunction max7360_keypad_probefunction max7360_keypad_remove
Annotated Snippet
struct max7360_keypad {
struct input_dev *input;
unsigned int rows;
unsigned int cols;
unsigned int debounce_ms;
int irq;
struct regmap *regmap;
unsigned short keycodes[MAX7360_MAX_KEY_ROWS * MAX7360_MAX_KEY_COLS];
};
static irqreturn_t max7360_keypad_irq(int irq, void *data)
{
struct max7360_keypad *max7360_keypad = data;
struct device *dev = max7360_keypad->input->dev.parent;
unsigned int val;
unsigned int row, col;
unsigned int release;
unsigned int code;
int error;
error = regmap_read(max7360_keypad->regmap, MAX7360_REG_KEYFIFO, &val);
if (error) {
dev_err(dev, "Failed to read MAX7360 FIFO");
return IRQ_NONE;
}
/* FIFO overflow: ignore it and get next event. */
if (val == MAX7360_FIFO_OVERFLOW) {
dev_warn(dev, "max7360 FIFO overflow");
error = regmap_read_poll_timeout(max7360_keypad->regmap, MAX7360_REG_KEYFIFO,
val, val != MAX7360_FIFO_OVERFLOW, 0, 1000);
if (error) {
dev_err(dev, "Failed to empty MAX7360 FIFO");
return IRQ_NONE;
}
}
if (val == MAX7360_FIFO_EMPTY) {
dev_dbg(dev, "Got a spurious interrupt");
return IRQ_NONE;
}
row = FIELD_GET(MAX7360_FIFO_ROW, val);
col = FIELD_GET(MAX7360_FIFO_COL, val);
release = val & MAX7360_FIFO_RELEASE;
code = MATRIX_SCAN_CODE(row, col, get_count_order(max7360_keypad->cols));
dev_dbg(dev, "key[%d:%d] %s\n", row, col, release ? "release" : "press");
input_event(max7360_keypad->input, EV_MSC, MSC_SCAN, code);
input_report_key(max7360_keypad->input, max7360_keypad->keycodes[code], !release);
input_sync(max7360_keypad->input);
return IRQ_HANDLED;
}
static int max7360_keypad_open(struct input_dev *pdev)
{
struct max7360_keypad *max7360_keypad = input_get_drvdata(pdev);
struct device *dev = max7360_keypad->input->dev.parent;
int error;
/* Somebody is using the device: get out of sleep. */
error = regmap_write_bits(max7360_keypad->regmap, MAX7360_REG_CONFIG,
MAX7360_CFG_SLEEP, MAX7360_CFG_SLEEP);
if (error)
dev_err(dev, "Failed to write max7360 configuration: %d\n", error);
return error;
}
static void max7360_keypad_close(struct input_dev *pdev)
{
struct max7360_keypad *max7360_keypad = input_get_drvdata(pdev);
struct device *dev = max7360_keypad->input->dev.parent;
int error;
/* Nobody is using the device anymore: go to sleep. */
error = regmap_write_bits(max7360_keypad->regmap, MAX7360_REG_CONFIG, MAX7360_CFG_SLEEP, 0);
if (error)
dev_err(dev, "Failed to write max7360 configuration: %d\n", error);
}
static int max7360_keypad_hw_init(struct max7360_keypad *max7360_keypad)
{
struct device *dev = max7360_keypad->input->dev.parent;
unsigned int val;
int error;
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/bitops.h`, `linux/dev_printk.h`, `linux/device/devres.h`, `linux/err.h`, `linux/init.h`, `linux/input.h`, `linux/input/matrix_keypad.h`.
- Detected declarations: `struct max7360_keypad`, `function max7360_keypad_irq`, `function max7360_keypad_open`, `function max7360_keypad_close`, `function max7360_keypad_hw_init`, `function max7360_keypad_build_keymap`, `function max7360_keypad_parse_fw`, `function max7360_keypad_probe`, `function max7360_keypad_remove`.
- Atlas domain: Driver Families / drivers/input.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.