drivers/input/keyboard/pmic8xxx-keypad.c
Source file repositories/reference/linux-study-clean/drivers/input/keyboard/pmic8xxx-keypad.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/input/keyboard/pmic8xxx-keypad.c- Extension
.c- Size
- 16932 bytes
- Lines
- 684
- 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/module.hlinux/platform_device.hlinux/kernel.hlinux/interrupt.hlinux/slab.hlinux/input.hlinux/bitops.hlinux/delay.hlinux/mutex.hlinux/regmap.hlinux/of.hlinux/input/matrix_keypad.h
Detected Declarations
struct pmic8xxx_kpfunction pmic8xxx_col_statefunction pmic8xxx_chk_sync_readfunction pmic8xxx_kp_read_datafunction pmic8xxx_kp_read_matrixfunction __pmic8xxx_kp_scan_matrixfunction pmic8xxx_detect_ghost_keysfunction pmic8xxx_kp_scan_matrixfunction pmic8xxx_kp_stuck_irqfunction pmic8xxx_kp_irqfunction pmic8xxx_kpd_initfunction pmic8xxx_kp_enablefunction pmic8xxx_kp_disablefunction pmic8xxx_kp_openfunction pmic8xxx_kp_closefunction pmic8xxx_kp_probefunction pmic8xxx_kp_suspendfunction pmic8xxx_kp_resume
Annotated Snippet
struct pmic8xxx_kp {
unsigned int num_rows;
unsigned int num_cols;
struct input_dev *input;
struct regmap *regmap;
int key_sense_irq;
int key_stuck_irq;
unsigned short keycodes[PM8XXX_MATRIX_MAX_SIZE];
struct device *dev;
u16 keystate[PM8XXX_MAX_ROWS];
u16 stuckstate[PM8XXX_MAX_ROWS];
u8 ctrl_reg;
};
static u8 pmic8xxx_col_state(struct pmic8xxx_kp *kp, u8 col)
{
/* all keys pressed on that particular row? */
if (col == 0x00)
return 1 << kp->num_cols;
else
return col & ((1 << kp->num_cols) - 1);
}
/*
* Synchronous read protocol for RevB0 onwards:
*
* 1. Write '1' to ReadState bit in KEYP_SCAN register
* 2. Wait 2*32KHz clocks, so that HW can successfully enter read mode
* synchronously
* 3. Read rows in old array first if events are more than one
* 4. Read rows in recent array
* 5. Wait 4*32KHz clocks
* 6. Write '0' to ReadState bit of KEYP_SCAN register so that hw can
* synchronously exit read mode.
*/
static int pmic8xxx_chk_sync_read(struct pmic8xxx_kp *kp)
{
int rc;
unsigned int scan_val;
rc = regmap_read(kp->regmap, KEYP_SCAN, &scan_val);
if (rc < 0) {
dev_err(kp->dev, "Error reading KEYP_SCAN reg, rc=%d\n", rc);
return rc;
}
scan_val |= 0x1;
rc = regmap_write(kp->regmap, KEYP_SCAN, scan_val);
if (rc < 0) {
dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc);
return rc;
}
/* 2 * 32KHz clocks */
udelay((2 * DIV_ROUND_UP(USEC_PER_SEC, KEYP_CLOCK_FREQ)) + 1);
return rc;
}
static int pmic8xxx_kp_read_data(struct pmic8xxx_kp *kp, u16 *state,
u16 data_reg, int read_rows)
{
int rc, row;
unsigned int val;
for (row = 0; row < read_rows; row++) {
rc = regmap_read(kp->regmap, data_reg, &val);
if (rc)
return rc;
dev_dbg(kp->dev, "%d = %d\n", row, val);
state[row] = pmic8xxx_col_state(kp, val);
}
return 0;
}
static int pmic8xxx_kp_read_matrix(struct pmic8xxx_kp *kp, u16 *new_state,
u16 *old_state)
{
int rc, read_rows;
unsigned int scan_val;
if (kp->num_rows < PM8XXX_MIN_ROWS)
read_rows = PM8XXX_MIN_ROWS;
else
read_rows = kp->num_rows;
Annotation
- Immediate include surface: `linux/module.h`, `linux/platform_device.h`, `linux/kernel.h`, `linux/interrupt.h`, `linux/slab.h`, `linux/input.h`, `linux/bitops.h`, `linux/delay.h`.
- Detected declarations: `struct pmic8xxx_kp`, `function pmic8xxx_col_state`, `function pmic8xxx_chk_sync_read`, `function pmic8xxx_kp_read_data`, `function pmic8xxx_kp_read_matrix`, `function __pmic8xxx_kp_scan_matrix`, `function pmic8xxx_detect_ghost_keys`, `function pmic8xxx_kp_scan_matrix`, `function pmic8xxx_kp_stuck_irq`, `function pmic8xxx_kp_irq`.
- 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.