drivers/input/rmi4/rmi_f3a.c
Source file repositories/reference/linux-study-clean/drivers/input/rmi4/rmi_f3a.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/input/rmi4/rmi_f3a.c- Extension
.c- Size
- 6176 bytes
- Lines
- 242
- 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/kernel.hlinux/rmi.hlinux/input.hlinux/slab.hrmi_driver.h
Detected Declarations
struct f3a_datafunction rmi_f3a_report_buttonfunction rmi_f3a_attentionfunction rmi_f3a_configfunction rmi_f3a_is_valid_buttonfunction rmi_f3a_map_gpiosfunction rmi_f3a_initializefunction rmi_f3a_probe
Annotated Snippet
struct f3a_data {
/* Query Data */
u8 gpio_count;
u8 register_count;
u8 data_regs[RMI_F3A_DATA_REGS_MAX_SIZE];
u16 *gpio_key_map;
struct input_dev *input;
struct rmi_function *f03;
bool trackstick_buttons;
};
static void rmi_f3a_report_button(struct rmi_function *fn,
struct f3a_data *f3a, unsigned int button)
{
u16 key_code = f3a->gpio_key_map[button];
bool key_down = !(f3a->data_regs[0] & BIT(button));
if (f3a->trackstick_buttons &&
button >= TRACKSTICK_RANGE_START &&
button <= TRACKSTICK_RANGE_END) {
rmi_f03_overwrite_button(f3a->f03, key_code, key_down);
} else {
rmi_dbg(RMI_DEBUG_FN, &fn->dev,
"%s: call input report key (0x%04x) value (0x%02x)",
__func__, key_code, key_down);
input_report_key(f3a->input, key_code, key_down);
}
}
static irqreturn_t rmi_f3a_attention(int irq, void *ctx)
{
struct rmi_function *fn = ctx;
struct f3a_data *f3a = dev_get_drvdata(&fn->dev);
struct rmi_driver_data *drvdata = dev_get_drvdata(&fn->rmi_dev->dev);
int error;
int i;
if (drvdata->attn_data.data) {
if (drvdata->attn_data.size < f3a->register_count) {
dev_warn(&fn->dev,
"F3A interrupted, but data is missing\n");
return IRQ_HANDLED;
}
memcpy(f3a->data_regs, drvdata->attn_data.data,
f3a->register_count);
drvdata->attn_data.data += f3a->register_count;
drvdata->attn_data.size -= f3a->register_count;
} else {
error = rmi_read_block(fn->rmi_dev, fn->fd.data_base_addr,
f3a->data_regs, f3a->register_count);
if (error) {
dev_err(&fn->dev,
"%s: Failed to read F3a data registers: %d\n",
__func__, error);
return IRQ_RETVAL(error);
}
}
for (i = 0; i < f3a->gpio_count; i++)
if (f3a->gpio_key_map[i] != KEY_RESERVED)
rmi_f3a_report_button(fn, f3a, i);
if (f3a->trackstick_buttons)
rmi_f03_commit_buttons(f3a->f03);
return IRQ_HANDLED;
}
static int rmi_f3a_config(struct rmi_function *fn)
{
struct f3a_data *f3a = dev_get_drvdata(&fn->dev);
struct rmi_driver *drv = fn->rmi_dev->driver;
const struct rmi_device_platform_data *pdata =
rmi_get_platform_data(fn->rmi_dev);
if (!f3a)
return 0;
if (pdata->gpio_data.trackstick_buttons) {
/* Try [re-]establish link to F03. */
f3a->f03 = rmi_find_function(fn->rmi_dev, 0x03);
f3a->trackstick_buttons = f3a->f03 != NULL;
}
drv->set_irq_bits(fn->rmi_dev, fn->irq_mask);
return 0;
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/rmi.h`, `linux/input.h`, `linux/slab.h`, `rmi_driver.h`.
- Detected declarations: `struct f3a_data`, `function rmi_f3a_report_button`, `function rmi_f3a_attention`, `function rmi_f3a_config`, `function rmi_f3a_is_valid_button`, `function rmi_f3a_map_gpios`, `function rmi_f3a_initialize`, `function rmi_f3a_probe`.
- 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.