drivers/input/serio/ams_delta_serio.c
Source file repositories/reference/linux-study-clean/drivers/input/serio/ams_delta_serio.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/input/serio/ams_delta_serio.c- Extension
.c- Size
- 5134 bytes
- Lines
- 191
- 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/irq.hlinux/platform_data/ams-delta-fiq.hlinux/platform_device.hlinux/regulator/consumer.hlinux/serio.hlinux/slab.hlinux/module.h
Detected Declarations
struct ams_delta_seriofunction check_datafunction ams_delta_serio_interruptfunction ams_delta_serio_openfunction ams_delta_serio_closefunction ams_delta_serio_initfunction ams_delta_serio_exit
Annotated Snippet
struct ams_delta_serio {
struct serio *serio;
struct regulator *vcc;
unsigned int *fiq_buffer;
};
static int check_data(struct serio *serio, int data)
{
int i, parity = 0;
/* check valid stop bit */
if (!(data & 0x400)) {
dev_warn(&serio->dev, "invalid stop bit, data=0x%X\n", data);
return SERIO_FRAME;
}
/* calculate the parity */
for (i = 1; i < 10; i++) {
if (data & (1 << i))
parity++;
}
/* it should be odd */
if (!(parity & 0x01)) {
dev_warn(&serio->dev,
"parity check failed, data=0x%X parity=0x%X\n", data,
parity);
return SERIO_PARITY;
}
return 0;
}
static irqreturn_t ams_delta_serio_interrupt(int irq, void *dev_id)
{
struct ams_delta_serio *priv = dev_id;
int *circ_buff = &priv->fiq_buffer[FIQ_CIRC_BUFF];
int data, dfl;
u8 scancode;
priv->fiq_buffer[FIQ_IRQ_PEND] = 0;
/*
* Read data from the circular buffer, check it
* and then pass it on the serio
*/
while (priv->fiq_buffer[FIQ_KEYS_CNT] > 0) {
data = circ_buff[priv->fiq_buffer[FIQ_HEAD_OFFSET]++];
priv->fiq_buffer[FIQ_KEYS_CNT]--;
if (priv->fiq_buffer[FIQ_HEAD_OFFSET] ==
priv->fiq_buffer[FIQ_BUF_LEN])
priv->fiq_buffer[FIQ_HEAD_OFFSET] = 0;
dfl = check_data(priv->serio, data);
scancode = (u8) (data >> 1) & 0xFF;
serio_interrupt(priv->serio, scancode, dfl);
}
return IRQ_HANDLED;
}
static int ams_delta_serio_open(struct serio *serio)
{
struct ams_delta_serio *priv = serio->port_data;
/* enable keyboard */
return regulator_enable(priv->vcc);
}
static void ams_delta_serio_close(struct serio *serio)
{
struct ams_delta_serio *priv = serio->port_data;
/* disable keyboard */
regulator_disable(priv->vcc);
}
static int ams_delta_serio_init(struct platform_device *pdev)
{
struct ams_delta_serio *priv;
struct serio *serio;
int irq, err;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->fiq_buffer = pdev->dev.platform_data;
if (!priv->fiq_buffer)
return -EINVAL;
priv->vcc = devm_regulator_get(&pdev->dev, "vcc");
if (IS_ERR(priv->vcc)) {
Annotation
- Immediate include surface: `linux/irq.h`, `linux/platform_data/ams-delta-fiq.h`, `linux/platform_device.h`, `linux/regulator/consumer.h`, `linux/serio.h`, `linux/slab.h`, `linux/module.h`.
- Detected declarations: `struct ams_delta_serio`, `function check_data`, `function ams_delta_serio_interrupt`, `function ams_delta_serio_open`, `function ams_delta_serio_close`, `function ams_delta_serio_init`, `function ams_delta_serio_exit`.
- 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.